chore(e2e): refactor and stablize tests (#18531)

pull/18539/head
karel-rehor 2020-06-16 16:59:05 +02:00 committed by GitHub
parent 42ef78d0c5
commit 72a415de51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 1541 additions and 322 deletions

View File

@ -23,6 +23,7 @@ jobs:
command: |
set +e
npm install
[ -f "/usr/local/bin/chromedriver" ] && cp /usr/local/bin/chromedriver node_modules/chromedriver/lib/chromedriver/chromedriver
./node_modules/chromedriver/bin/chromedriver --version
npm test; TEST_RESULT=$?
npm run report:html

View File

@ -1,19 +1,14 @@
{
"active": "development",
"default_user": {
"username": "admin",
"password": "changeit",
"org": "qa",
"bucket": "qa"
},
"development" : {
"config_id" : "development",
"protocol": "http",
"host" : "localhost",
"port" : "9999",
"influx_url": "http://localhost:9999",
"def_ctx": "/",
"headless": false,
"sel_docker": false,
"deployment": "nightly_docker",
"create_method": "REST",
"docker_name": "influx2_solo",
"browser": "chrome",
"screenshot_dir": "screenshots",
"influxdb": {
@ -22,16 +17,60 @@
"window_size": {
"width": "1024",
"height": "933"
},
"default_user": {
"username": "admin",
"password": "changeit",
"org": "qa",
"bucket": "qa",
"token": "TEST_TOKEN"
}
},
},
"nightly" : {
"config_id": "nightly",
"protocol": "http",
"host": "aws-somewhere",
"port": "9999",
"influx_url": "http://localhost:9999",
"def_ctx": "/",
"headless": true,
"browser": "chrome",
"screenshot_dir": "screenshots"
"screenshot_dir": "screenshots",
"deployment": "local_build",
"create_method": "CLI_DOCKER",
"influx_path": "../bin/linux/influx",
"docker_name": "influx2_solo",
"default_user": {
"username": "hibou",
"password": "ENV",
"org": "qa",
"bucket": "qa",
"token": "ENV"
}
},
"cloud": {
"config_id" : "cloud",
"influx_url": "https://eu-central-1-1.aws.cloud2.influxdata.com",
"def_ctx": "/",
"headless": false,
"sel_docker": false,
"deployment": "cloud",
"create_method": "SKIP",
"browser": "chrome",
"screenshot_dir": "screenshots",
"influxdb": {
"version" : "2.0.0"
},
"window_size": {
"width": "1024",
"height": "933"
},
"default_user": {
"username": "qa1@bonitoo4influxdata.com",
"password": "ENV",
"org": "qa1@bonitoo4influxdata.com",
"bucket": "qa1A",
"orgid": "8864d10598fc08a7",
"bucketid": "7e0486a588f2f20a",
"token": "ENV"
}
}
}

View File

@ -450,7 +450,7 @@ Feature: Dashboards - Dashboard - Cell Edit
Then the time machine preview canvas axes are not present
Then the time machine empty graph error message is:
"""
type error 1:1-1:7: undefined identifier "Muffin"
error @1:1-1:7: undefined identifier Muffin
"""
When click the cell edit save button
Then the cell named "Kliky" contains a graph error
@ -458,7 +458,7 @@ Feature: Dashboards - Dashboard - Cell Edit
#When hover over the error icon of the cell "Kliky"
Then the cell error message of the cell named "Kliky" is:
"""
type error 1:1-1:7: undefined identifier "Muffin"
error @1:1-1:7: undefined identifier Muffin
"""
@tested

View File

@ -81,7 +81,7 @@ Feature: Dashboards - Dashboard - Base
Then popup is not loaded
When toggle context menu of dashboard cell named "вре́менный"
When click cell content popover add note
Then click popup cancel simple button
Then click note popup cancel
Then popup is not loaded
When toggle context menu of dashboard cell named "вре́менный"
When click cell content popover add note

View File

@ -33,7 +33,7 @@ Feature: Dashboards - Dashboard - Note Cell
Then dismiss the popup
Then popup is not loaded
When click dashboard add note button
Then click popup cancel simple button
Then click note popup cancel
Then popup is not loaded
Scenario: Add Note with markdown
@ -79,7 +79,7 @@ Feature: Dashboards - Dashboard - Note Cell
When click cell content popover edit note
Then main "Edit" note popup is loaded
# TODO edit text and verify - need to push on to higher priority tests
When click popup cancel simple button
When click note popup cancel
Scenario: Delete note
When toggle context menu of dashboard cell named "Note"

View File

@ -0,0 +1,124 @@
@feature-dataExplorer
@dataExplorer-dataExplorer
Feature: Data explorer
As a user I want to Create queries in Data Explorer
Scenario: Create a new bucket and add data
Given I reset the environment
Given run setup over REST "DEFAULT"
When open the signin page
When UI sign in user "DEFAULT"
When click nav menu item "LoadData"
Then the buckets tab is loaded
When click the Create Bucket button
Then the Create Bucket Popup is loaded
When input the name of the bucket as "bucket_explorer_test"
When click the Create Bucket popup Create button
Then the bucket named "bucket_explorer_test" is in the list
When click add data button for bucket "bucket_explorer_test"
Then the add data popover for the bucket "bucket_explorer_test" is visible
When click bucket card popover item "Line Protocol"
Then the first page of the Line Protocol Wizard is loaded
When click radio button "Enter Manually"
Then the data point text area is visible
When enter "12" datapoints with value named "foo" starting at "-2h" with "fibonacci" data of type "int" and prec "ms"
When click the Line Protocol wizard precision dropdown
When click the line Protocol wizard precision "ms"
#When enter "<any>" into the line protocol text area
When click the Line Protocol wizard continue button
Then the Line Protocol wizard step status message is "Data Written Successfully"
When click the Line Protocol wizard finish button
Scenario: Create a simple query
#When click nav menu item "Explorer"
When click on the bucket named "bucket_explorer_test"
Then the Data Explorer page is loaded
When choose bucket named "bucket_explorer_test"
When choose the item "fibonacci" in builder card "1"
When choose the item "foo" in builder card "2"
When choose the item "bucketSteps" in builder card "3"
When click the submit button
Then the time machine graph is shown
Scenario: Hover over graph
When hover over the graph
Then the graph data point infobox is visible
Scenario: Zoom graph horizontal
When get the current graph
When move horizontally to "2/5" of the graph
When drag horizontally to "3/5" of the graph
Then the graph has changed
Scenario: Unzoom graph
When get the current graph
When Click at the point "{"x": "1/2", "y": "1/2"}" of the graph
Then the graph has changed
Scenario: Zoom graph vertical and refresh
When get the current graph
When move vertically to "2/5" of the graph
When drag vertically to "3/5" of the graph
Then the graph has changed
When click the refresh button
Then the graph has changed
Scenario: Turn on the automatic refresh and check the graph changes
When click the refresh button
When get the current graph
When click the automatic refresh - paused
When select the automatic refresh "5s"
When wait "6" seconds
Then the graph has changed
When click the automatic refresh - active
When select the automatic refresh "paused"
Scenario: Create second query with Script Editor
When click the time machine add query button
Then there are "2" time machine query tabs
#When right click on the time machine query tab named "Query 2"
#When click on "edit" in the query tab menu
#When input a new query tab name as "testQueryTab"
When click the Script Editor button
When paste into Script Editor text area
"""
from(bucket: "bucket_explorer_test")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "fibonacci")
"""
When click the submit button
Then the time machine graph is shown
Then the graph has changed
Scenario: Change graph view type
When click the graph view type dropdown
When select the graph view type "Graph + Single Stat"
Then the graph view type is Graph plus Single Stat
Scenario: Change the graph time range and view raw data
When click the graph time range dropdown
When select the graph time range "6h"
Then the graph has changed
When click the view raw data toggle
Then the raw data table is visible
Scenario: Use aggregate function
When click the view raw data toggle
Then the time machine graph is shown
When click on the time machine query tab named "Query 1"
#When search for function "mean"
When select the function "mean"
When click the submit button
Then the graph has changed
Scenario: Delete query tab
When right click on the time machine query tab named "Query 2"
When click on "remove" in the query tab menu
Then there are "1" time machine query tabs

View File

@ -183,7 +183,7 @@ Scenario: Add Manual Line Protocol Data to Default
When API sign in user "DEFAULT"
Then the bucket "DEFAULT" for user "DEFAULT" contains:
"""
{ "points": 12, "field": "foo", "measurement": "fibonacci", "start": "-3h", "vals": ["1","233"], "rows": ["1","-1"] }
{ "points": 12, "field": "foo", "measurement": "fibonacci", "start": "-3h", "vals": [1,233], "rows": ["0","-1"] }
"""
@error-collateral
@ -231,7 +231,7 @@ Scenario: Add Manual Line Protocol Data to Default
#Then the bucket "DEFAULT" for user "DEFAULT" contains "20" datapoints of "hydro" data with value named "level" starting at "-60h"
Then the bucket "DEFAULT" for user "DEFAULT" contains:
"""
{ "points": 20, "field": "level", "measurement": "hydro", "start": "-60h", "vals": "skip", "rows": ["1","-1"], "name": "hydro" }
{ "points": 20, "field": "level", "measurement": "hydro", "start": "-72h", "vals": "skip", "rows": ["0","-1"], "name": "hydro" }
"""
@tested

View File

@ -120,9 +120,11 @@ Feature: Load Data - Tokens
@error-collateral
Scenario: Sort By Name
Then the first tokens are sorted by description as "admin's Token, Campbells Soup, Dismaland, La Femme a la perle, La Jocande"
When click the tokens sort By Name button
When click the tokens sorter button
When click the tokens sorter item "Description Asc"
Then the first tokens are sorted by description as "Un enterrement a Ornans, Nu descendant un escalier, La Jocande, La Femme a la perle, Dismaland"
When click the tokens sort By Name button
When click the tokens sorter button
When click the tokens sorter item "Description Desc"
Then the first tokens are sorted by description as "admin's Token, Campbells Soup, Dismaland, La Femme a la perle, La Jocande"
@error-collateral
@ -162,8 +164,8 @@ Feature: Load Data - Tokens
Scenario Outline: Delete Token
When hover over token card described as "<DESCR>"
When click the delete button of the token card described as "<DESCR>"
#When click delete confirm of the token card described as "<DESCR>"
When click token card popover delete confirm
When click delete confirm of the token card described as "<DESCR>"
#When click token card popover delete confirm
Then the success notification contains "Token was deleted successfully"
Then the tokens list does not contain the token described as "<DESCR>"
Then close all notifications

View File

@ -85,6 +85,8 @@ After(async function (scenario /*, callback */) {
// fs.mkdir(`./${__config.screenshot_dir}`, () => {})
// }
__reportedResetOnce = true;
let uri = scenario.sourceLocation.uri
let feature = uri.substring(uri.lastIndexOf("/") + 1).replace('.','-')
let name = scenario.pickle.name.trim().replace(' ', '_');
@ -133,6 +135,9 @@ After(async function (scenario /*, callback */) {
AfterAll(async function ( ) {
__reportedResetOnce = false;
if(__liveDataGenRunning) {
console.log("killing live generator");
__killLiveDataGen = true;

View File

@ -22,16 +22,21 @@
"babel-preset-env": "^1.7.0",
"chai": "^4.2.0",
"chai-match": "^1.1.1",
"chromedriver": "^80.0.0",
"chromedriver": "^83.0.0",
"copy-paste": "^1.3.0",
"csv": "^5.3.1",
"cucumber": "^5.1.0",
"cucumber-html-reporter": "^5.0.0",
"cucumber-junit-convert": "^1.0.2",
"cucumber-pretty": "^1.5.2",
"eslint": "^6.1.0",
"eslint": "^7.1.0",
"geckodriver": "^1.16.2",
"mkdirp": "^0.5.1",
"selenium-webdriver": "^4.0.0-alpha.7"
},
"dependencies": {
"@influxdata/influxdb-client": "^1.3.0",
"@influxdata/influxdb-client-apis": "^1.3.0",
"expect.js": "^0.3.1"
}
}

View File

@ -9,8 +9,8 @@ const popupFormElementError = '[data-testid=form--element-error]';
const formInputError = '[data-testid=input-error]';
const popupOverlay = '[data-testid=overlay]';
const popupDismiss = '[data-testid=overlay--header] button[class*=dismiss]';
const popupCancel = '[data-testid=overlay--container] button[data-testid=button--cancel]';
const popupCancelSimple = '[data-testid=overlay--container] button[title=Cancel]';
const popupCancel = '[data-testid=overlay] button[data-testid=button--cancel]';
const popupCancelSimple = '[data-testid=overlay--body] button[title=Cancel] ';
const popupWizardContinue = '[data-testid=overlay--body] [data-testid=next]';
const popupSave = '[data-testid=overlay--container] button[data-testid=button--save] ';
const popupSaveSimple = '[data-testid=overlay--footer] button[title=\'Save\']';

View File

@ -0,0 +1,38 @@
const { By, Condition, until, StaleElementReferenceError} = require('selenium-webdriver');
const urlCtx = 'signin';
const emailInput = '[data-testid=\'input-field\']';
const passwordInput = '[data-testid=\'visibility-input\']';
const logInButton = '[data-testid=\'button\']';
const logInPanel = '[data-testid=\'panel\']';
class cloudLoginPage {
constructor(driver) {
//super(driver);
this.urlCtx = urlCtx;
this.driver = driver;
}
async waitToLoad(timeout = 10000){
await this.driver.wait(until.elementLocated(By.css(logInPanel)), timeout,
`Login controls failed to load in ${timeout} milliseonds `);
}
async getEmailInput(){
return await this.driver.findElement(By.css(emailInput));
}
async getPasswordInput(){
return await this.driver.findElement(By.css(passwordInput));
}
async getLogInButton(){
return await this.driver.findElement(By.css(logInButton));
}
}
module.exports = cloudLoginPage;

View File

@ -8,7 +8,7 @@ const graphToolTips = '[data-testid=page-control-bar] [data-testid=graphtips-que
//const addCellButtonHeader = '//*[@data-testid=\'page-header--right\']//*[@data-testid=\'button\'][.//*[text()=\'Add Cell\']]';
const addCellButtonHeader = '//*[@data-testid=\'page-control-bar--left\']//*[@data-testid=\'button\'][.//*[text()=\'Add Cell\']]';
//const addNoteButton = '//*[@data-testid=\'page-header--right\']//*[@data-testid=\'button\'][.//*[text()=\'Add Note\']]';
const addNoteButton = '//*[@data-testid=\'page-control-bar--left\']//*[@data-testid=\'button\'][.//*[text()=\'Add Note\']]';
const addNoteButton = '[data-testid=add-note--button]';
//const variablesButton = '//*[@data-testid=\'page-header--right\']//*[@data-testid=\'button\'][.//*[text()=\'Variables\']]';
const variablesButton = '//*[@data-testid=\'page-control-bar--left\']//*[@data-testid=\'button\'][.//*[text()=\'Variables\']]';
//const timeLocaleDropdown = '//*[@data-testid=\'page-header--right\']//*[@data-testid=\'dropdown--button\'][.//*[contains(@class,\'annotate\')]]';
@ -64,6 +64,8 @@ const notePopupEditorPreview = '[data-testid=overlay--body] .note-editor--previe
const notePopupEditorPreviewTag = '[data-testid=overlay--body] .note-editor--preview %TAG%';
const notePopupEditorPreviewText = '[data-testid=overlay--body] .note-editor--preview .markdown-format';
const notePopupGuideLink = '[href*=\'markdownguide.org\']';
const notePopupCancel = '[data-testid=overlay--footer] button[title=Cancel]';
const notePopupSave = '[data-testid=overlay--footer] button[title=Save]';
const notePopover = '[data-testid=popover--dialog]';
const notePopoverContents = '[data-testid=popover--dialog] .markdown-format';
@ -83,7 +85,7 @@ class dashboardPage extends influxPage {
await super.isLoaded([{type: 'css', selector: pageTitle},
{type: 'css', selector: graphToolTips},
{type: 'xpath', selector: addCellButtonHeader},
{type: 'xpath', selector: addNoteButton},
{type: 'css', selector: addNoteButton},
{type: 'xpath', selector: variablesButton},
{type: 'xpath', selector: timeLocaleDropdown},
{type: 'xpath', selector: autorefresh},
@ -122,7 +124,7 @@ class dashboardPage extends influxPage {
}
async getAddNoteButton(){
return await this.driver.findElement(By.xpath(addNoteButton));
return await this.driver.findElement(By.css(addNoteButton));
}
async getVariablesButton(){
@ -249,6 +251,14 @@ class dashboardPage extends influxPage {
return await this.driver.findElement(By.css(notePopupGuideLink));
}
async getNotePopupCancel(){
return await this.driver.findElement(By.css(notePopupCancel));
}
async getNotePopupSave(){
return await this.driver.findElement(By.css(notePopupSave));
}
async getCellNoteByName(name){
return await this.driver.findElement(By.xpath(cellNoteByName.replace('%NAME%', name)));
}

View File

@ -13,6 +13,39 @@ const timeRangeDropdown = '//*[@data-testid=\'flex-box\']/div[3]';
//const scriptEditToggle = '[data-testid=switch-to-script-editor] '; //N.B. disappears when in Script edit mode - not good candidate for page load check
//const queryBuildToggle = '[data-testid=switch-to-query-builder]'; //N.B. not present when in Query builder mode - not good candidate for page load check
const submitQueryButton = '[data-testid=time-machine-submit-button]';
const bucketSelector = '[data-testid=bucket-selector]';
const builderCard = '[data-testid=builder-card]';
const graphCanvas = '[data-testid^=giraffe-layer]';
const cellCanvasLine = '//*[contains(@class, \' cell \')][.//*[text()=\'%NAME%\']]//*[@data-testid=\'giraffe-layer-line\']';
const graphHoverLine = '[data-testid=giraffe-layer-hover-line]';
const canvasAxes = '//*[@data-testid=\'giraffe-axes\']'; //'[@data-testid=\'giraffe-axes\']';
const refreshGraphButton = '//*[@class=\'autorefresh-dropdown--pause\'][@data-testid=\'square-button\']'; '//*[@class=\'cell--header\'][./*[text()=\'%NAME%\']]';
const refreshDropdownPaused = '//*[@class=\'autorefresh-dropdown paused\'][.//*[@data-testid=\'dropdown\']]';
const refreshDropdownActive = '//*[@class=\'autorefresh-dropdown\'][.//*[@data-testid=\'dropdown\']]';
const refreshDropdownItem = '[id=\'auto-refresh-%ITEM%\']'; //'//*[@data-testid=\'dropdown-menu--contents\'][.//*[text()=\'%ITEM%\']]'; //*[contains(@class, ' cell ')][. '//*[id=\'auto-refresh-%ITEM%\'][@data-testid=\'dropdown-item\']';
const addQueryButton = '[class=time-machine-queries--tabs] [data-testid=square-button]';
const queryTabByName = '//*[contains(@class,\'query-tab\')][./*[text()=\'%NAME%\']]';
const queryTabMenuItem = '//*[@data-testid=\'right-click--%ITEM%-tab\']';
const queryTabNameInput = '//*[contains(@class,\'query-tab__active\')][.//*[contains(@class,\'cf-input-xs\')]]';
const scriptEditorButton = '[data-testid=switch-to-script-editor]';
const scriptMonacoEditor = '.inputarea';
const viewTypeDropdown = '[data-testid=page-control-bar--left] [data-testid=\'view-type--dropdown\']';
const viewType = '//*[@class=\'cf-dropdown-item--children\'][.//*[text()=\'%TYPE%\']]';
const singleStatText = '[data-testid=single-stat--text]';
const rawDataToggle = '[data-testid=raw-data--toggle]';
const rawDataTable = '[data-testid=raw-data-table]';
const functionSearchInput = '//*[@data-testid=\'function-selector\'][.//*[contains(@class,\'tag-selector--search\')]]';
//TODO - more controls
@ -74,10 +107,119 @@ class dataExplorerPage extends influxPage {
return await this.driver.findElement(By.css(submitQueryButton));
}
async getBucketSelector(){
return await this.driver.findElement(By.css(bucketSelector));
}
async getItemFromSelectorList(bucket){
return await this.driver.findElement(By.css(`[data-testid='selector-list ${bucket}']`));
}
async getBuilderCard(){
return await this.driver.findElements(By.css(builderCard));
}
async getBuilderCardByIndex(index){
return (await this.driver.findElements(By.css(builderCard)))[index - 1];
}
async getGraphCanvas(){
return await this.driver.findElement(By.css(graphCanvas));
}
async getCanvasLine(){
return await this.driver.findElement(By.css(graphCanvas));
}
async getGraphHoverLine(){
return await this.driver.findElement(By.css(graphHoverLine));
}
async getCanvasAxes(){
return await this.driver.findElement(By.xpath(canvasAxes));
}
async getRefreshGraphButton(){
return await this.driver.findElement(By.xpath(refreshGraphButton));
}
async getRefreshDropdownPaused(){
return await this.driver.findElement(By.xpath(refreshDropdownPaused));
}
async getRefreshDropdownActive(){
return await this.driver.findElement(By.xpath(refreshDropdownActive));
}
//async getRefreshDropdownItem(item){
// return await this.driver.findElement(By.css(`[data-testid='dropdown-item'][id='auto-refresh-${item}']`));
//}
async getRefreshDropdownItem(item){
return await this.driver.findElement(By.css(refreshDropdownItem.replace('%ITEM%', item)));
}
async getAddQueryButton(){
return await this.driver.findElement(By.css(addQueryButton));
}
async getQueryTabByName(name){
return await this.driver.findElement(By.xpath(queryTabByName.replace('%NAME%', name)));
}
async getQueryTabMenuItem(item){
return await this.driver.findElement(By.xpath(queryTabMenuItem.replace('%ITEM%', item)));
}
async getQueryTabNameInput(){
return await this.driver.findElement(By.xpath(queryTabNameInput));
}
async getScriptEditorButton(){
return await this.driver.findElement(By.css(scriptEditorButton));
}
async getScriptMonacoEditor(){
return await this.driver.findElement(By.css(scriptMonacoEditor));
}
async getViewTypeDropdown(){
return await this.driver.findElement(By.css(viewTypeDropdown));
}
async getViewType(type){
return await this.driver.findElement(By.xpath(viewType.replace('%TYPE%', type)));
}
async getSingleStatText(){
return await this.driver.findElement(By.css(singleStatText));
}
async getRawDataToggle(){
return await this.driver.findElement(By.css(rawDataToggle));
}
async getRawDataTable(){
return await this.driver.findElement(By.css(rawDataTable));
}
async getTimeRangeDropdownItem(item){
return await this.driver.findElement(By.css(`[data-testid='dropdown-item-past${item}']`));
}
async getFunctionSearchInput(){
return await this.driver.findElement(By.xpath(functionSearchInput));
}
async getSelectorListFunction(funct){
return await this.driver.findElement(By.css(`[data-testid='selector-list ${funct}']`));
}
//TODO - more element getters
}
module.exports = dataExplorerPage;

View File

@ -39,15 +39,15 @@ const configurationDescrInput = '[data-testid=input-field][title*=\'Configuratio
const configurationPluginsSideBar = '//*[*[text()=\'Plugins\']]//div[contains(@class,\'side-bar--tabs\')]';
//Telegraf wizard edit plugin
const pluginDockerEditEndpoint = '//*[label/span[text()=\'endpoint\']]//*[@data-testid=\'input-field\']';
const pluginK8SEditEndpoint = '//*[label/span[text()=\'url\']]//*[@data-testid=\'input-field\']';
const pluginNGINXEditEndpoint = '//*[label/span[text()=\'urls\']]//*[@data-testid=\'input-field\']';
const pluginDockerEditEndpoint = '//*[.//*[text()=\'endpoint\']][@data-testid=\'form--element\']//*[@data-testid=\'input-field\']';
const pluginK8SEditEndpoint = '//*[.//*[text()=\'url\']][@data-testid=\'form--element\']//*[@data-testid=\'input-field\']';
const pluginNGINXEditEndpoint = '//*[.//*[text()=\'urls\']][@data-testid=\'form--element\']//*[@data-testid=\'input-field\']';
const pluginNGINXAddUrlButton = '[data-testid=button][title=\'Add to list of urls\']';
const pluginNGINXDeleteFirstURL = '[data-testid=confirmation-button--button][title=\'Delete\']:nth-of-type(1)';
const pluginNGINXDeleteURLConfirmButton = '[data-testid=confirmation-button--confirm-button]';
const pluginNGINXURLListItems = '[data-testid=overlay--body] [data-testid=\'grid--column\'] [data-testid=index-list]';
const pluginRedisServersEditEndpoint = '//*[label/span[text()=\'servers\']]//*[@data-testid=\'input-field\']';
const pluginRedisPasswordEditEndpoint = '//*[label/span[text()=\'password\']]//*[@data-testid=\'input-field\']';
const pluginRedisServersEditEndpoint = '//*[.//*[text()=\'servers\']][@data-testid=\'form--element\']//*[@data-testid=\'input-field\']';
const pluginRedisPasswordEditEndpoint = '//*[.//*[text()=\'password\']][@data-testid=\'form--element\']//*[@data-testid=\'input-field\']';
//Telegraf wizard step 3
const codeToken = '//pre[contains(text(), \'TOKEN\')]';

View File

@ -3,21 +3,23 @@ const settingsPage = require(__srcdir + '/pages/settings/settingsPage.js');
const tokensFilter = '[data-testid=input-field--filter]';
const genTokenButton = '[data-testid=dropdown-button--gen-token]';
const tokenListing = '[data-testid=index-list]';
const descHeader = '[data-testid=index-list--header-cell]:nth-of-type(1)';
const statusHeader = '[data-testid=index-list--header-cell]:nth-of-type(2)';
const tokenListing = '[data-testid=resource-list]';
//const descHeader = '[data-testid=index-list--header-cell]:nth-of-type(1)';// header no longer present 10.6
//const statusHeader = '[data-testid=index-list--header-cell]:nth-of-type(2)'; //header no longer present 10.6
//const createVariableBody = '[data-testid=button-create-initial]';
const tokenCellTemplate = '//*[@data-testid=\'table-cell\'][.//span[text()="%DESCR%"]]';
const tokenCellTemplate = '//*[@data-testid=\'resource-card\'][.//span[text()="%DESCR%"]]';
const generateTokenDropdownBtn = '[data-testid=dropdown-button--gen-token]';
const generateTokenItem = '[data-testid=\'dropdown-item generate-token--%ITEM%\']';
const tokenCardDisableToggle = '//*[td//span[text() = \'%DESCR%\']]//*[@data-testid=\'slide-toggle\']';
const tokenCardDisableToggle = '//*[@data-testid = \'resource-card\'][.//span[text() = \'%DESCR%\']]//*[@data-testid=\'slide-toggle\']';
const tokenSorterButton = '[data-testid=resource-sorter--button]';
const tokenSorterItem = '[data-testid=resource-sorter--%ITEM%]';
const tokensSortByDescription = '//*[@data-testid=\'index-list--header-cell\'][text()=\'Description\']';
const tokenDescription = '//*[@data-testid=\'editable-name\'][.//span[text()=\'%DESCR%\']]';
const tokenDescriptionEditBtn = '//*[@data-testid=\'editable-name\'][.//span[text()=\'%DESCR%\']]/div[@data-testid=\'editable-name--toggle\']';
const tokenDescriptionEditInput = '//*[@data-testid=\'editable-name\'][.//span[text()=\'%DESCR%\']]//input';
const tokenCardDeleteButton = '//*[@data-testid=\'table-row\'][.//span[text()="%DESCR%"]]//*[@data-testid=\'delete-token--button\']';
const tokenDescription = '//*[@data-testid=\'resource-editable-name\'][.//span[text()=\'%DESCR%\']]';
const tokenDescriptionEditBtn = '//*[./*[@data-testid=\'resource-editable-name\'][.//span[text()=\'%DESCR%\']]]//*[@data-testid=\'resource-editable-name--button\']';
const tokenDescriptionEditInput = '//*[./*[@data-testid=\'resource-editable-name--input--default\']]/input';
const tokenCardDeleteButton = '//*[@data-testid=\'resource-card\'][.//span[text()="%DESCR%"]]//*[@data-testid=\'context-menu\']';
// next selector is deprecated - todo clean up
const tokenCardDeleteConfirm = '//*[@data-testid=\'table-row\'][.//span[text()="%DESCR%"]]//*[text()=\'Confirm\']';
const tokenCardDeleteConfirm = '//*[@data-testid=\'resource-card\'][.//span[text()="%DESCR%"]]//*[@data-testid=\'delete-token\']';
const tokenCardPopoverDeletConfirm = '//*[@data-testid=\'delete-token--popover--dialog\']//*[text() = \'Confirm\']';
// Generate Read/Write token popup
@ -54,8 +56,7 @@ class tokensTab extends settingsPage{
{type: 'css', selector: tokensFilter},
{type: 'css', selector: genTokenButton},
{type: 'css', selector: tokenListing},
{type: 'css', selector: descHeader},
{type: 'css', selector: statusHeader},
{type: 'css', selector: tokenSorterButton}
]
);
}
@ -139,7 +140,16 @@ class tokensTab extends settingsPage{
}
async getTokenCardDescriptions(){
return await this.driver.findElements(By.xpath('//*[@data-testid=\'editable-name\']//span'));
return await this.driver.findElements(By.xpath('//*[@data-testid=\'resource-editable-name\']'));
}
async getTokenSorterButton(){
return await this.driver.findElement(By.css(tokenSorterButton));
}
async getTokenSorterItem(item){
return await this.driver.findElement(By.css(tokenSorterItem.replace('%ITEM%',
item.toLowerCase().replace(' ','-'))));
}
async getTokensSortByDescription(){
@ -155,7 +165,7 @@ class tokensTab extends settingsPage{
}
async getTokenDescriptionEditInput(descr){
return await this.driver.findElement(By.xpath(tokenDescriptionEditInput.replace('%DESCR%', descr)));
return await this.driver.findElement(By.xpath(tokenDescriptionEditInput));
}
async getTokenReviewTokenCode(){

View File

@ -34,8 +34,8 @@ const checkCardLabelPill = '//*[@data-testid=\'check-card\'][.//*[text()=\'%NAME
const checkCardLabelRemove = '//*[@data-testid=\'check-card\'][.//*[text()=\'%NAME%\']]//*[@data-testid=\'label--pill--delete %LABEL%\']';
const checkCardCloneButton = '//*[@data-testid=\'check-card\'][.//*[text()=\'%NAME%\']]//*[@data-testid=\'context-menu\'][./*[contains(@class,\'duplicate\')]]';
const checkCardCloneConfirm = '//*[@data-testid=\'check-card\'][.//*[text()=\'%NAME%\']]//*[@data-testid=\'context-menu-item\'][text()=\'Clone\']';
const checkCardOpenHistory = '//*[@data-testid=\'check-card\'][.//*[text()=\'%NAME%\']]//*[@data-testid=\'context-menu\'][./*[contains(@class,\'eye-open\')]]';
const checkCardOpenHistoryConfirm = '//*[@data-testid=\'check-card\'][.//*[text()=\'%NAME%\']]//*[@data-testid=\'context-menu-item\']';
const checkCardOpenHistory = '//*[@data-testid=\'check-card\'][.//*[text()=\'%NAME%\']]//*[@data-testid=\'context-history-menu\'][./*[contains(@class,\'eye-open\')]]';
const checkCardOpenHistoryConfirm = '//*[@data-testid=\'check-card\'][.//*[text()=\'%NAME%\']]//*[@data-testid=\'context-history-task\']';
const checkCardDeleteButton = '//*[@data-testid=\'check-card\'][.//*[text()=\'%NAME%\']]//*[@data-testid=\'context-delete-menu\']';
const checkCardDeleteConfirm = '//*[@data-testid=\'check-card\'][.//*[text()=\'%NAME%\']]//*[@data-testid=\'context-delete-task\']'

View File

@ -23,9 +23,9 @@ const previewThresholdHandleByLevel = '[class*=\'threshold-marker--handle thresh
// Configure Check Controls
// Properties
const confChkIntervalInput = '//*[./label/span[text() = \'Schedule Every\']]//*[@data-testid=\'duration-input\']';
const confChkOffset = '//*[./label/span[text() = \'Offset\']]//*[@data-testid=\'duration-input\']';
const confChkAddTagButton = '//*[./label/span[text() = \'Tags\']]//*[@data-testid=\'dashed-button\']';
const confChkIntervalInput = '[data-testid=schedule-check]';
const confChkOffset = '[data-testid=offset-options]';
const confChkAddTagButton = '//*[./*/*[text() = \'Tags\']]//*[@data-testid=\'dashed-button\']';
// Status Message Template
const confChkMessageTextArea = '[data-testid=status-message-textarea]';
@ -104,11 +104,11 @@ class checkEditPage extends influxPage {
}
async getConfChkIntervalInput(){
return await this.driver.findElement(By.xpath(confChkIntervalInput));
return await this.driver.findElement(By.css(confChkIntervalInput));
}
async getConfChkOffset(){
return await this.driver.findElement(By.xpath(confChkOffset));
return await this.driver.findElement(By.css(confChkOffset));
}
async getConfChkAddTagButton(){
@ -182,15 +182,15 @@ class checkEditPage extends influxPage {
}
async getConfTagRuleKeyInputOfTag(index){
return await this.driver.findElement(By.css(confTagRuleKeyInputOfTag.replace('%INDEX%', parseInt(index) + 1)));
return await this.driver.findElement(By.css(confTagRuleKeyInputOfTag.replace('%INDEX%', parseInt(index) + 2)));
}
async getConfTagRuleValueInputOfTag(index){
return await this.driver.findElement(By.css(confTagRuleValueInputOfTag.replace('%INDEX%', parseInt(index) + 1)));
return await this.driver.findElement(By.css(confTagRuleValueInputOfTag.replace('%INDEX%', parseInt(index) + 2)));
}
async getConfTagRuleDimissOfTag(index){
return await this.driver.findElement(By.css(confTagRuleDimissOfTag.replace('%INDEX%', parseInt(index) + 1)));
return await this.driver.findElement(By.css(confTagRuleDimissOfTag.replace('%INDEX%', parseInt(index) + 2)));
}
}

View File

@ -2,12 +2,12 @@ const influxPage = require(__srcdir + '/pages/influxPage.js');
const { By } = require('selenium-webdriver');
const alertHistoryTitle = '[data-testid=alert-history-title]';
const filterInput = '//*[./*[@data-testid=\'input-field--default\']]//*[@data-testid=\'input-field\']';
const filterInput = '//*[./*[@data-testid=\'check-status-input--default\']]//*[@data-testid=\'check-status-input\']';
const eventRows = '.event-row';
const eventRowCheckNameField = '//*[./*[@class=\'event-row\']][%INDEX%]//a';
const eventRowsAtLevel = '//*[./*[@class=\'event-row\']]//*[contains(@class,\'level-table-field--%LEVEL%\')]';
const eventMarkersDiv = '[data-testid=event-markers]';
const eventFilterExamplesDropdown = '[data-testid=dropdown-menu]';
const eventFilterExamplesDropdown = '[data-testid=check-status-dropdown--contents]';
const eventMarkerByIndex = '[data-testid=event-markers] > div:nth-of-type(%INDEX%)';
const eventMarkers = '[data-testid=event-markers] > *';
const eventMarkersByType = '[data-testid=event-markers] > [class*=\'event-marker--line__%TYPE%\'';
@ -15,6 +15,12 @@ const eventMarkerToggleByType = '[data-testid=event-marker-vis-toggle-%TYPE%] >
const canvasGraphAxes = 'canvas.giraffe-axes';
const canvasGraphContent = 'canvas.giraffe-layer-line';
const graphToolTip = '[data-testid=giraffe-tooltip]';
const graphToolTipColumnValue = '//*[@data-testid=\'giraffe-tooltip-table\']/*[.//*[text()=\'%COLUMN%\']]/*[2]';
const eventMarkerTooltip = '[data-testid=app-wrapper]';
const eventMarkerColumnValue = '//*[@data-testid=\'app-wrapper\']//*[./*[text()=\'%COLUMN%\']]/*[2]';
const eventTable = '.event-table';
@ -96,6 +102,22 @@ class checkStatusHistoryPage extends influxPage {
return await this.driver.findElement(By.css(eventMarkerToggleByType.replace('%TYPE%', type.toLowerCase())));
}
async getEventMarkerTooltip(){
return await this.driver.findElement(By.css(eventMarkerTooltip));
}
async getGraphToolTip(){
return await this.driver.findElement(By.css(graphToolTip));
}
async graphToolTipColumnValue(column){
return await this.driver.findElement(By.xpath(graphToolTipColumnValue.replace('%COLUMN%', column)));
}
async eventMarkerColumnValue(column){
return await this.driver.findElement(By.xpath(eventMarkerColumnValue.replace('%COLUMN%', column)));
}
}
module.exports = checkStatusHistoryPage;

View File

@ -25,7 +25,7 @@ class settingsPage extends influxPage {
}
async getTabByName(name){
return await this.driver.findElement(By.xpath(`${tabsXpath}//div[@data-testid='tabs--tab' and @id='${name.toLowerCase()}']`));
return await this.driver.findElement(By.xpath(`${tabsXpath}//div[@data-testid='${name.toLowerCase()}--tab']`));
}
}

View File

@ -8,13 +8,13 @@ const nameSort = '[data-testid=resource-list--sorter]:nth-of-type(1)';
const typeSort = '[data-testid=resource-list--sorter]:nth-of-type(2)';
const createVariableEmpty = '[data-testid=resource-list--body] [data-testid=add-resource-dropdown--button]';
const createVariableItem = '[data-testid=add-resource-dropdown--%ITEM%]';
const variableCardNamed = '//*[@data-testid=\'resource-card\'][.//*[text()=\'%NAME%\']]';
const variableCardNames = '//*[@data-testid=\'resource-name\']/span';
const variableCardName = '//*[@data-testid=\'resource-name\']//span[text()=\'%NAME%\']';
const variableCardContextMenu = '//*[@data-testid=\'resource-card\'][.//span[text()=\'%NAME%\']]//*[@data-testid=\'context-menu\']';
const variableCardContextMenuItem = '//*[@data-testid=\'resource-card\'][.//span[text()=\'%NAME%\']]//*[button[@data-testid=\'context-menu\']]//button[text()=\'%ITEM%\']';
const variableCardContextDelete = '//*[@data-testid=\'resource-card\'][.//span[text() = \'%NAME%\']]//*[@data-testid=\'context-delete-menu\']';
const variableCardContextDeleteConfirm = '//*[@data-testid=\'resource-card\'][.//span[text() = \'%NAME%\']]//*[@data-testid=\'context-delete-variable\']';
const variableCardNamed = '//*[@data-testid=\'resource-card variable\'][.//*[text()=\'%NAME%\']]';
const variableCardNames = '[data-testid^=\'variable-card--name\'] span';
const variableCardName = '//*[@data-testid=\'variable-card--name %NAME%\']//span[text()=\'%NAME%\']';
const variableCardContextMenu = '//*[@data-testid=\'resource-card variable\'][.//span[text()=\'%NAME%\']]//*[@data-testid=\'context-menu\']';
const variableCardContextMenuItem = '//*[@data-testid=\'resource-card variable\'][.//span[text()=\'%NAME%\']]//*[button[@data-testid=\'context-menu\']]//button[text()=\'%ITEM%\']';
const variableCardContextDelete = '//*[@data-testid=\'resource-card variable\'][.//span[text() = \'%NAME%\']]//*[@data-testid=\'context-delete-menu\']';
const variableCardContextDeleteConfirm = '//*[@data-testid=\'resource-card variable\'][.//span[text() = \'%NAME%\']]//*[@data-testid=\'context-delete-variable\']';
const urlCtx = 'variables';
@ -34,15 +34,15 @@ const createVariableQueryCodeMirror = '.CodeMirror';
const createVariableQueryMonacoEdit = '.monaco-editor';
const createVariableTextArea = '[data-testid=overlay--body] [data-testid=textarea]';
const createVariableTypeDropdownItem = '[data-testid=\'variable-type-dropdown-%ITEM%\']';
const createVariableDefaultValDropdown = '//*[@data-testid=\'form--element\'][label/span[text() = \'Select A Default\']]//*[@data-testid=\'dropdown--button\']';
const createVariableDefaultValDropdown = '//*[@data-testid=\'form--element\'][.//*[text() = \'Select A Default\']]//*[contains(@data-testid,\'dropdown--button\')]';
const createVariableInfoPara = '//*[@data-testid=\'grid--column\'][p[contains(text(), \'ontains\')]]';
const createVariableDefaultValDropdownItem = '[data-testid=dropdown-item][id=\'%ITEM%\']';
const createVariableDefaultValCSVDropdownItem = '//*[@data-testid=\'dropdown-item\']//*[text() = \'%ITEM%\']';
// edit variable popup
const editVariableTypeDropdown = '//*[@data-testid=\'form--element\'][.//span[text() = \'Type\']]//*[@data-testid=\'dropdown--button\']';
const editVariableTypeDropdownItem = '//*[@data-testid=\'form--element\'][.//span[text() = \'Type\']]//*[@data-testid=\'dropdown-item\'][@id=\'%ITEM%\']';
const editVariableNameInput = '//*[@data-testid=\'form--element\'][.//span[text() = \'Name\']]//input';
const editVariableTypeDropdown = '[data-testid=\'variable-type-dropdown--button\']';
const editVariableTypeDropdownItem = '[data-testid=\'variable-type-dropdown-%ITEM%\']';
const editVariableNameInput = '//*[@data-testid=\'form--element\'][.//*[text()=\'Name\']]//input';
const editWarnVariablSubmit = '[data-testid=danger-confirmation-button]';
const editVariableNameChangeSubmit = '[data-testid=rename-variable-submit]';
@ -186,11 +186,11 @@ class variablesTab extends settingsPage{
}
async getVariableCardNames(){
return await this.driver.findElements(By.xpath(variableCardNames));
return await this.driver.findElements(By.css(variableCardNames));
}
async getVariableCardName(name){
return await this.driver.findElement(By.xpath(variableCardName.replace('%NAME%', name)));
return await this.driver.findElement(By.xpath(variableCardName.replace(/%NAME%/g, name)));
}
async getNameSort(){
@ -213,12 +213,12 @@ class variablesTab extends settingsPage{
}
async getEditVariableTypeDropdown(){
return await this.driver.findElement(By.xpath(editVariableTypeDropdown));
return await this.driver.findElement(By.css(editVariableTypeDropdown));
}
async getEditVariableTypeDropdownItem(item){
return await this.driver.findElement(By.xpath(editVariableTypeDropdownItem.replace('%ITEM%', item)));
return await this.driver.findElement(By.css(editVariableTypeDropdownItem.replace('%ITEM%', item.toLowerCase())));
}
async getEditVariableNameInput(){

View File

@ -0,0 +1,16 @@
import { AfterAll, Given, Then, When } from 'cucumber';
const cloudSteps = require(__srcdir + '/steps/cloudSteps.js');
let cSteps = new cloudSteps(__wdriver);
When(/^setup default cloud user$/, async () => {
await cSteps.setupDefaultCloudUser();
});
When(/^I open the cloud login$/, {timeout: 30000}, async () => {
await cSteps.openCloudLogin();
});
When(/^log in to the cloud$/, async () => {
await cSteps.logInToCloud();
});

View File

@ -11,7 +11,8 @@ let iSteps = new influxSteps(__wdriver);
Given(/^I reset the environment$/, async () => {
await bSteps.driver.sleep(1000); //since gets called after scenarios, need a short delay to avoid promise resolution issues
await flush();
await bSteps.resetEnvironment();
//await flush();
});
/*
@ -62,7 +63,7 @@ When(/^close all notifications$/, async() => {
// newUser if not DEFAULT should follow {username: 'name', password: 'password', org: 'org', bucket: 'bucket'}
Given(/^run setup over REST "(.*?)"$/, async( newUser ) => {
await influxUtils.flush();
//await influxUtils.flush();
if(newUser === 'DEFAULT'){
await influxUtils.setupUser(__defaultUser);
@ -76,8 +77,28 @@ Given(/^run setup over REST "(.*?)"$/, async( newUser ) => {
});
Given(/^run setup user "(.*)"$/, {timeout: 15000}, async newUser => {
await influxUtils.setupNewUser(newUser);
});
Given(/^run setup over CLI docker "(.*?)"$/, async( newUser ) => {
if(newUser === 'DEFAULT'){
await influxUtils.setupUserDockerCLI(__defaultUser);
}else{
let user = JSON.parse(newUser);
if(user.password.length < 8 ){
throw Error(`Password: ${user.password} is shorter than 8 chars`);
}
await influxUtils.setupUser(user);
}
await bSteps.driver.sleep(1000); //give system chance to write everything down
});
When(/^API sign in user "(.*?)"$/, async username => {
await influxUtils.signIn((username === 'DEFAULT') ? __defaultUser.username : username).then(async () => {
await influxUtils.signInAxios((username === 'DEFAULT') ? __defaultUser.username : username).then(async () => {
// await sSteps.driver.sleep(1500)
}).catch(async err => {
@ -125,16 +146,18 @@ When(/^write sine data for org "(.*?)" to bucket "(.*?)"$/, async (org, bucket)
});
When(/^query sine data for org of user "(.*)" from bucket "(.*)"$/, async (user, bucket) => {
let startTime = '-1d';
let org = influxUtils.getUser(user).orgid;
let query = `from(bucket: "${bucket}")
|> range(start: ${startTime})
|> filter(fn: (r) => r._measurement == "sinus")
|> filter(fn: (r) => r._field == "point")`;
//For Inspection purposes
When(/^simple query data "(.*)" for org of user "(.*)" from bucket "(.*)" over "(.*)"$/, async (items, userName, bucket, period) => {
let results = await influxUtils.query(org, query);
console.log('DEBUG results: ' + results);
let dataDef = JSON.parse(items.replace(/\\/g,""));
let targetBucket = (bucket === 'DEFAULT') ? __defaultUser.bucket : 'fred';
let query = `from(bucket: "${targetBucket}")
|> range(start: ${period})
|> filter(fn: (r) => r._measurement == "${dataDef.name}")
|> filter(fn: (r) => r._field == "${dataDef.measurement}")`;
let results = await influxUtils.query(userName, query);
console.info('INFO results: ' + JSON.stringify(results));
});
@ -153,15 +176,25 @@ When(/^API create a dashboard named "(.*?)" for user "(.*?)"$/, async (name, use
});
//Troubleshoot method
When(/^API get all dashboards for user "(.*?)"$/, async user => {
let dboards = await influxUtils.getDashboards(user);
console.info(`DUMP dboards for user (${user}):\n ${JSON.stringify(dboards)}`);
});
When(/^API create a bucket named "(.*)" for user "(.*)"$/, async (bucket, username) => {
let user = await influxUtils.getUser((username === 'DEFAULT') ? __defaultUser.username : username);
await influxUtils.createBucket(user.orgid, user.org, bucket);
});
When(/^API create a label "(.*)" described as "(.*)" with color "(.*)" for user "(.*)"$/,
async (labelName, labelDescr, labelColor, user) => {
let orgID = influxUtils.getUser((user === 'DEFAULT') ? __defaultUser.username : user).orgid;
await influxUtils.createLabel(orgID, labelName, labelDescr, labelColor);
async (labelName, labelDescr, labelColor, userName) => {
await influxUtils.createLabel(userName, labelName, labelDescr, labelColor);
});
When(/^open page "(.*?)" for user "(.*?)"$/, async (page, username) => {
@ -249,16 +282,19 @@ When(/^generate a line protocol testdata file "(.*)" based on:$/, async (filePat
await influxUtils.genLineProtocolFile(filePath, def);
});
When(/^generate a line protocol testdata for user "(.*)" based on:$/, async (user, def) => {
await influxUtils.writeLineProtocolData((user === 'DEFAULT')? __defaultUser: await influxUtils.getUser(user),
def);
When(/^generate a line protocol testdata for user "(.*)" based on:$/, async (userName, def) => {
//await influxUtils.writeLineProtocolData((user === 'DEFAULT')? __defaultUser: await influxUtils.getUser(user),
// def);
await influxUtils.writeLineProtocolData(userName, def);
});
When(/^create the "(.*)" variable "(.*)" with default "(.*)" for user "(.*)" with values:$/,
async(type, name, defVal, user, values) => {
async(type, name, defVal, userName, values) => {
type = type === 'csv' ? 'constant' : type.toLowerCase();
let orgID = influxUtils.getUser((user === 'DEFAULT') ? __defaultUser.username : user).orgid;
await influxUtils.createVariable(orgID, name, type, values, defVal)
//let orgID = influxUtils.getUser((user === 'DEFAULT') ? __defaultUser.username : user).orgid;
await influxUtils.createVariable(userName, name, type, values, defVal)
});
//For troubleshooting - up to 5 min
@ -274,14 +310,14 @@ When(/^press the "(.*)" key$/, async key => {
await bSteps.pressKeyAndWait(key);
});
When(/^create a new template from the file "(.*)" for user "(.*)"$/, async (filepath, user) => {
let orgID = influxUtils.getUser((user === 'DEFAULT') ? __defaultUser.username : user).orgid;
await influxUtils.createTemplateFromFile(filepath, orgID);
When(/^create a new template from the file "(.*)" for user "(.*)"$/, async (filepath, userName) => {
//let orgID = influxUtils.getUser((user === 'DEFAULT') ? __defaultUser.username : user).orgid;
await influxUtils.createTemplateFromFile(userName, filepath);
});
When(/^create check over API from file "(.*)" for user "(.*)"$/, async (filepath, user) => {
let orgID = influxUtils.getUser((user === 'DEFAULT') ? __defaultUser.username : user).orgid;
await influxUtils.createAlertCheckFromFile(filepath, orgID);
When(/^create check over API from file "(.*)" for user "(.*)"$/, async (filepath, userName) => {
//let orgID = influxUtils.getUser((user === 'DEFAULT') ? __defaultUser.username : user).orgid;
await influxUtils.createAlertCheckFromFile(userName, filepath);
});
When(/^remove file "(.*)" if exists$/, async filePath => {
@ -369,4 +405,10 @@ When(/^clear the popover label selector filter$/, async () => {
await bSteps.clearDashboardLabelsFilter();
});
//For Inspection
When(/^get authorizations for user "(.*)"$/, async userName => {
let auths = await influxUtils.getAuthorizations(userName);
console.info(`Authorizations for ${userName}:\n${JSON.stringify(auths)}`);
});

View File

@ -96,6 +96,10 @@ When(/^click cell content popover add note$/, async () => {
await dbdSteps.clickDashboardPopOverlayAddNote();
});
Then(/^click note popup cancel$/, async () => {
await dbdSteps.clickNotePopupCance();
})
When(/^click cell content popover edit note$/, async () => {
await dbdSteps.clickDashboardPopOverlayEditNote();
});

View File

@ -1,4 +1,4 @@
import { Then } from 'cucumber';
import {Then, When} from 'cucumber';
const dataExplorerSteps = require(__srcdir + '/steps/dataExplorer/dataExplorerSteps.js');
let deSteps = new dataExplorerSteps(__wdriver);
@ -8,3 +8,140 @@ Then(/^the Data Explorer page is loaded$/, {timeout: 2 * 5000}, async () => {
await deSteps.verifyIsLoaded();
//await deSteps.verifyHeaderContains('Data Explorer');
});
When(/^choose bucket named "(.*)"$/, async (bucket) => {
await deSteps.chooseBucket(bucket);
});
When(/^choose the item "(.*)" in builder card "(.*)"$/, async (measurement,index) => {
await deSteps.chooseItemFromBuilderCard(measurement, index);
})
When(/^click the submit button$/, async () => {
await deSteps.clickQuerySubmitButton();
});
Then(/^the time machine graph is shown$/, async() => {
await deSteps.verifyGraphVisible();
});
When(/^hover over the graph$/, async() => {
await deSteps.hoverOverGraph();
});
Then(/^the graph data point infobox is visible$/, async () => {
await deSteps.verifyGraphDataPointInfoBox();
});
When(/^get the current graph$/, async() => {
await deSteps.getCurrentGraph();
});
When(/^move horizontally to "(.*)" of the graph$/, async (fraction) => {
await deSteps.moveToHorizontalFractionOfGraph(fraction);
});
When(/^drag horizontally to "(.*)" of the graph$/, async (fraction) => {
await deSteps.dragToHorizonatalFractionOfGraph(fraction);
});
Then(/^the graph has changed$/, async() => {
await deSteps.verifyGraphChange();
});
When(/^Click at the point "(.*)" of the graph$/, async (target) => {
let fracs = JSON.parse(target);
await deSteps.clickPointWithinGraphByFractions(fracs);
});
When(/^move vertically to "(.*)" of the graph$/, async (fraction) => {
await deSteps.moveToVerticalFractionOfGraph(fraction);
});
When(/^drag vertically to "(.*)" of the graph$/, async (fraction) => {
await deSteps.dragToVerticalFractionOfGraph(fraction);
});
When(/^click the refresh button$/, async () => {
await deSteps.clickQuerySubmitButton();
});
When(/^click the automatic refresh - paused$/, async () => {
await deSteps.clickRefreshDropdownPaused();
});
When(/^click the automatic refresh - active$/, async () => {
await deSteps.clickRefreshDropdownActive();
});
When(/^select the automatic refresh "(.*)"$/, async (item) => {
await deSteps.selectRefreshDropdownItem(item);
});
When(/^click the time machine add query button$/, async () => {
await deSteps.clickAddQueryButton();
});
When(/^right click on the time machine query tab named "(.*)"$/, async (title) => {
await deSteps.rightClickQueryTabTitle(title);
});
When(/^click on the time machine query tab named "(.*)"$/, async (title) => {
await deSteps.clickQueryTabTitle(title);
});
When(/^click on "(.*)" in the query tab menu$/, async (item) => {
await deSteps.selectQueryTabMenuItem(item);
});
When(/^input a new query tab name as "(.*)"$/, async (name) => {
await deSteps.setQueryTabName(name);
});
When(/^click the Script Editor button$/, async () => {
await deSteps.clickScriptEditorButton();
});
When(/^paste into Script Editor text area$/, { timeout: 20000 }, async text => {
await deSteps.pasteIntoScriptEditor(text);
});
When(/^click the graph view type dropdown$/, async () => {
await deSteps.clickViewTypeDropdown();
});
When(/^select the graph view type "(.*)"$/, async (type) => {
await deSteps.selectViewType(type);
});
Then(/^the graph view type is Graph plus Single Stat$/, async () => {
await deSteps.verifySingleStatTextVisible();
});
When(/^click the view raw data toggle$/, async () => {
await deSteps.clickViewRawDataToggle();
});
Then(/^the raw data table is visible$/, async () => {
await deSteps.verifyRawDataTableVisible();
});
When(/^click the graph time range dropdown$/, async () => {
await deSteps.clickTimeRangeDropdown();
});
When(/^select the graph time range "(.*)"$/, async (item) => {
await deSteps.selectTimeRangeDropdownItem(item);
});
When(/^search for function "(.*)"$/, async (funct) => {
await deSteps.searchFunction(funct);
});
When(/^select the function "(.*)"$/, async (funct) => {
await deSteps.selectFunctionFromList(funct);
});

View File

@ -286,9 +286,8 @@ Then(/^the bucket "(.*)" for user "(.*)" contains "(.*)" datapoints of "(.*)" da
count, mode, value, start);
});
Then(/^the bucket "(.*)" for user "(.*)" contains:$/, async (bucket, user, def) => {
await bktTabSteps.verifyBucketContainsByDef((bucket === 'DEFAULT') ? __defaultUser.bucket : bucket,
(user === 'DEFAULT')? __defaultUser: await influxUtils.getUser(user), def);
Then(/^the bucket "(.*)" for user "(.*)" contains:$/, async (bucket, userName, def) => {
await bktTabSteps.verifyBucketContainsByDef(bucket,userName, def);
});
When(/^add the file "(.*)" to the Line Protocol Wizard file upload$/, async filePath => {

View File

@ -74,11 +74,8 @@ When(/^Enter the value "(.*)" for the card "(.*)"$/, {timeout: 10000}, async ( n
});
Then(/^the named query "(.*)" by user "(.*)" on the bucket "(.*)" contains the values "(.*)"$/,
async (queryName, user, bucket, values) => {
await scrTabSteps.verifyNamedQueryResponseValues(queryName,
user,
(bucket === 'DEFAULT') ? __defaultUser.bucket : bucket,
values);
async (queryName, userName, bucketName, values) => {
await scrTabSteps.verifyNamedQueryResponseValues(queryName, userName, bucketName, values);
});
Then(/^the delete button of the scraper card named "(.*)" is not present$/, async name => {

View File

@ -4,7 +4,7 @@ const tokensSteps = require(__srcdir + '/steps/loadData/tokensSteps.js');
let tknSteps = new tokensSteps(__wdriver);
Then(/^the tokens tab is loaded$/, async () => {
Then(/^the tokens tab is loaded$/, {timeout: 10000}, async () => {
await tknSteps.isLoaded();
});
@ -163,6 +163,14 @@ Then(/^the first tokens are sorted by description as "(.*)"$/, async list => {
await tknSteps.verifyTokenSortOrder(list);
});
When(/^click the tokens sorter button$/, async () => {
await tknSteps.clickTokensSorterButton();
});
When(/^click the tokens sorter item "(.*)"$/, async item => {
await tknSteps.clickTokensSorterItem(item);
});
When(/^click the tokens sort By Name button$/, async () => {
await tknSteps.clickTokensSortByName();
});

View File

@ -3,7 +3,7 @@ const checkStatusHistorySteps = require(__srcdir + '/steps/monitoring/checkStatu
let ckStatHistSteps = new checkStatusHistorySteps(__wdriver);
Then(/^the Check statusses page is loaded$/, async() => {
Then(/^the Check statusses page is loaded$/, {timeout: 10000}, async() => {
await ckStatHistSteps.isLoaded();
await ckStatHistSteps.verifyIsLoaded();
});

View File

@ -38,16 +38,29 @@ class baseSteps{
await this.driver.sleep(timeout);
}
async resetEnvironment(){
switch(__config.deployment.toUpperCase()){
case 'CLOUD':
if(!__reportedResetOnce) console.log("---- TODO Resetting against cloud -----");
break;
case 'NIGHTLY_DOCKER':
if(!__reportedResetOnce) console.log("----- Resetting against nightly docker -----");
await influxUtils.flush();
break;
case 'LOCAL_BUILD':
if(!__reportedResetOnce) console.log("---- TODO Resetting against local build -----");
//todo review if works against local build
await influxUtils.flush();
break;
}
}
async clearBrowserLocalStorage(){
await this.driver.executeScript('window.localStorage.clear()');
}
/* async open(url){
await this.driver.get(url);
} */
async openBase(){
await this.driver.get( `${__config.protocol}://${__config.host}:${__config.port}/`);
await this.driver.get( __config.influx_url);
await this.driver.wait(function(driver = this.driver) {
return driver.executeScript('return document.readyState').then(function(readyState) {
return readyState === 'complete';
@ -57,7 +70,7 @@ class baseSteps{
}
async openContext(ctx){
await this.driver.get( `${__config.protocol}://${__config.host}:${__config.port}/` + ctx);
await this.driver.get( `${__config.influx_url}/` + ctx);
await this.driver.wait(function(driver = this.driver) {
return driver.executeScript('return document.readyState').then(function(readyState) {
return readyState === 'complete';
@ -276,7 +289,11 @@ class baseSteps{
}
//Example def { "points": 20, "field": "level", "measurement": "hydro", "start": "-60h", "vals": "skip", "rows": ["1","-1"] }
async verifyBucketContainsByDef(bucket, user, def){
async verifyBucketContainsByDef(bucketName, userName, def){
let user = influxUtils.getUser(userName);
let bucket = (bucketName === 'DEFAULT') ? user.bucket : bucketName;
let define = JSON.parse(def);
@ -286,34 +303,21 @@ class baseSteps{
|> filter(fn: (r) => r._measurement == "${define.measurement}")
|> filter(fn: (r) => r._field == "${define.field}")`;
let results = await influxUtils.query(user.orgid, query);
let resTable = await (await results.split('\r\n')).filter((row) => {
return row.split(',').length > 9;
});
let headers = resTable[0].split(',');
headers.shift();
let mesIn = headers.indexOf('_measurement');
let fieldIn = headers.indexOf('_field');
let valIn = headers.indexOf('_value');
let results = await influxUtils.query(userName, query);
for(let i = 0; i < define.rows.length; i++){
let recs;
if(parseInt(define.rows[i]) === -1){ // last record
recs = resTable[resTable.length - 1].split(',');
recs = results[results.length - 1];
}else{ //by normal index {0,1,2...N}
recs = resTable[parseInt(define.rows[i])].split(',');
recs = results[parseInt(define.rows[i])];
}
recs.shift();
expect(recs[fieldIn]).to.equal(define.field);
expect(recs[mesIn]).to.equal(define.measurement);
expect(recs['_field']).to.equal(define.field);
expect(recs['_measurement']).to.equal(define.measurement);
if(typeof(define.vals) !== 'string'){
expect(recs[valIn]).to.equal(define.vals[i]);
expect(recs['_value']).to.equal(define.vals[i]);
}
}

View File

@ -0,0 +1,46 @@
const baseSteps = require(__srcdir + '/steps/baseSteps.js');
//const createOrgPage = require(__srcdir + '/pages/createOrgPage.js');
const cloudLoginPage = require(__srcdir + '/pages/cloud/cloudLoginPage.js');
const influxUtils = require(__srcdir + '/utils/influxUtils.js');
class cloudSteps extends baseSteps {
constructor(driver){
super(driver);
//this.createOrgPage = new createOrgPage(driver);
this.loginPage = new cloudLoginPage(driver);
}
//for driver sync
async isLoaded(){
//await this.createOrgPage.isLoaded();
}
//for assrtions
async verifyIsLoaded(){
//this.assertVisible(await this.createOrgPage.getInputOrgName());
//this.assertVisible(await this.createOrgPage.getInputBucketName());
//this.assertVisible(await this.createOrgPage.getbuttonCancel());
//this.assertVisible(await this.createOrgPage.getbuttonCreate());
}
async setupDefaultCloudUser(){
await influxUtils.setupCloudUser('DEFAULT');
}
async openCloudLogin(){
await this.openBase();
//wait for login form to load
await this.loginPage.waitToLoad(10000);
}
async logInToCloud(){
await this.typeTextAndWait(await this.loginPage.getEmailInput(), __defaultUser.username);
await this.typeTextAndWait(await this.loginPage.getPasswordInput(), __defaultUser.password);
await this.clickAndWait(await this.loginPage.getLogInButton());
}
}
module.exports = cloudSteps;

View File

@ -522,7 +522,7 @@ class cellOverlaySteps extends influxSteps {
}
__dataBuffer.rect[name] = rect;
//debug why resize not saved
//await influxUtils.signIn('admin');
//await influxUtils.signInAxios('admin');
//let dashboards = await influxUtils.getDashboards();
//console.log("DEBUG dashboards " + JSON.stringify(dashboards));

View File

@ -151,7 +151,7 @@ class dashboardSteps extends influxSteps {
}
__dataBuffer.rect[name] = rect;
//debug why resize not saved
//await influxUtils.signIn('admin');
//await influxUtils.signInAxios('admin');
//let dashboards = await influxUtils.getDashboards();
//console.log("DEBUG dashboards " + JSON.stringify(dashboards));
@ -269,6 +269,10 @@ class dashboardSteps extends influxSteps {
});
}
async clickNotePopupCance(){
await this.clickAndWait(await this.dbdPage.getNotePopupCancel());
}
async clickDashboardPopOverlayEditNote(){
await this.clickAndWait(await this.dbdPage.getcellPopoverContentsEditNote(), async () => {
await this.driver.sleep(1000);
@ -301,8 +305,8 @@ class dashboardSteps extends influxSteps {
await this.verifyElementContainsText(await this.dbdPage.getPopupTitle(), 'Edit Note');
await this.assertVisible(await this.dbdPage.getNotePopupCodeMirror());
await this.assertVisible(await this.dbdPage.getPopupDismiss());
await this.assertVisible(await this.dbdPage.getPopupCancelSimple());
await this.assertVisible(await this.dbdPage.getPopupSaveSimple());
await this.assertVisible(await this.dbdPage.getNotePopupCancel());
await this.assertVisible(await this.dbdPage.getNotePopupSave());
await this.assertVisible(await this.dbdPage.getNotePopupNoDataToggle());
await this.assertVisible(await this.dbdPage.getNotePopupEditorPreview());
}
@ -312,8 +316,8 @@ class dashboardSteps extends influxSteps {
await this.verifyElementContainsText(await this.dbdPage.getPopupTitle(), `${state} Note`);
await this.assertVisible(await this.dbdPage.getNotePopupCodeMirror());
await this.assertVisible(await this.dbdPage.getPopupDismiss());
await this.assertVisible(await this.dbdPage.getPopupCancelSimple());
await this.assertVisible(await this.dbdPage.getPopupSaveSimple());
await this.assertVisible(await this.dbdPage.getNotePopupCancel());
await this.assertVisible(await this.dbdPage.getNotePopupSave());
await this.assertVisible(await this.dbdPage.getNotePopupEditorPreview());
await this.assertVisible(await this.dbdPage.getNotePopupGuideLink());
}
@ -449,7 +453,7 @@ class dashboardSteps extends influxSteps {
await resizer.click();
//debug why resize not saved
//await influxUtils.signIn('admin');
//await influxUtils.signInAxios('admin');
//let dashboards = await influxUtils.getDashboards();
//console.log("DEBUG dashboards " + JSON.stringify(dashboards));
@ -463,7 +467,7 @@ class dashboardSteps extends influxSteps {
await this.dbdPage.getCellByName(name).then(async cell => {
//debug why resize not saved
//await influxUtils.signIn('admin');
//await influxUtils.signInAxios('admin');
//let dashboards = await influxUtils.getDashboards();
//console.log("DEBUG dashboards " + JSON.stringify(dashboards));

View File

@ -1,18 +1,20 @@
const expect = require('chai').expect;
const influxSteps = require(__srcdir + '/steps/influx/influxSteps.js');
const dataExplorerPage = require(__srcdir + '/pages/dataExplorer/dataExplorerPage.js');
class dataExplorerSteps extends influxSteps{
class dataExplorerSteps extends influxSteps {
constructor(driver){
constructor(driver) {
super(driver);
this.dePage = new dataExplorerPage(driver);
}
async isLoaded(){
async isLoaded() {
await this.dePage.isLoaded();
}
async verifyIsLoaded(){
async verifyIsLoaded() {
this.assertVisible(await this.dePage.getTimeLocaleDropdown());
this.assertVisible(await this.dePage.getGraphTypeDropdown());
this.assertVisible(await this.dePage.getCustomizeGraphButton());
@ -24,6 +26,345 @@ class dataExplorerSteps extends influxSteps{
this.assertVisible(await this.dePage.getSubmitQueryButton());
}
async chooseBucket(bucket) {
await this.dePage.getBucketSelector(await this.dePage.getItemFromSelectorList(bucket).then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(500); //todo better wait
});
}))
}
/*
async chooseMeasurement(measurement, index) {
await this.dePage.getBuilderCardByIndex(await this.dePage.getItemFromSelectorList(measurement).then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(500); //todo better wait
});
}), index)
}
*/
async chooseItemFromBuilderCard(measurement, index) {
let card = await this.dePage.getBuilderCardByIndex(parseInt(index));
await this.dePage.getItemFromSelectorList(measurement).then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(500); //todo better wait
});
})
}
async clickQuerySubmitButton() {
await this.dePage.getSubmitQueryButton().then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(500); //todo better wait
});
})
}
async verifyGraphVisible(){
await this.assertVisible(await this.dePage.getGraphCanvas());
}
async hoverOverGraph(){
await this.dePage.getCanvasLine().then(async canvas => {
let action = await this.driver.actions();
let rect = await canvas.getRect();
let x = parseInt(rect.x);
let y = parseInt(rect.y);
let centX = parseInt((rect.width / 2) + x);
let centY = parseInt((rect.height / 2) + y);
await action.move({x : centX, y: centY, duration: 1000})
.perform();
await this.driver.sleep(200); // todo better wait - let graph update
//await this.dbdPage.getCellHoverBox().then(async box => {
// await this.assertVisible(box);
// console.log("DEBUG got cell hover box");
//})
});
}
async verifyGraphDataPointInfoBox(){
await this.assertVisible(await this.dePage.getGraphHoverLine());
}
async getCurrentGraph(){
await this.dePage.getCanvasAxes().then(async canvasAxes => {
if(typeof __dataBuffer.graphAxes === 'undefined') {
__dataBuffer.graphAxes = [];
}
/* eslint-disable require-atomic-updates */
__dataBuffer.graphAxes = await this.driver
.executeScript('return arguments[0].toDataURL(\'image/png\');', canvasAxes);
// console.log('DEBUG __dataBuffer.graphCellAxes[' + name + "] " +
// __dataBuffer.graphCellAxes[name]);
await this.dePage.getCanvasLine().then(async canvasLine => {
if(typeof __dataBuffer.graphLine === 'undefined') {
__dataBuffer.graphLine = [];
}
__dataBuffer.graphLine = await this.driver
.executeScript('return arguments[0].toDataURL(\'image/png\');', canvasLine);
// console.log('DEBUG __dataBuffer.graphCellLine[' + name + "] " +
// __dataBuffer.graphCellLine[name]);
});
});
}
async verifyGraphChange(){
await this.driver.sleep(1000); //troubleshoot canvas update issue
await this.dePage.getCanvasAxes().then(async canvasAxes => {
let currentAxes = await this.driver
.executeScript('return arguments[0].toDataURL(\'image/png\');', canvasAxes);
await expect(currentAxes).to.not.equal(__dataBuffer.graphAxes);
await this.dePage.getCanvasLine().then(async canvasLine => {
let currentLine = await this.driver
.executeScript('return arguments[0].toDataURL(\'image/png\');', canvasLine);
await expect(currentLine).to.not.equal(__dataBuffer.graphLine);
});
});
}
async moveToHorizontalFractionOfGraph(fraction){
let fract = fraction.split('/');
let denom = fract[1];
let numer = fract[0];
await this.dePage.getCanvasLine().then(async canvas => {
let action = await this.driver.actions();
let rect = await canvas.getRect();
let x = parseInt(rect.x);
let y = parseInt(rect.y);
let targetX = parseInt(((rect.width/denom) * numer) + x);
let targetY = parseInt((rect.height / 2) + y);
await action.move({x: targetX, y: targetY, duration: 1000})
.perform();
await this.driver.sleep(200); // todo better wait - let graph update
});
}
async dragToHorizonatalFractionOfGraph(fraction){
let fract = fraction.split('/');
let denom = fract[1];
let numer = fract[0];
await this.dePage.getCanvasLine().then(async canvas => {
let action = await this.driver.actions();
let rect = await canvas.getRect();
let x = parseInt(rect.x);
let y = parseInt(rect.y);
let targetX = parseInt(((rect.width/denom) * numer) + x);
let targetY = parseInt((rect.height / 2) + y);
await action.press()
.move({x: targetX, y: targetY, duration: 1000})
.release()
.perform();
await this.driver.sleep(200); // todo better wait - let graph update
});
}
async clickPointWithinGraphByFractions(fracs, name) {
let xfract = {};
let yfract = {};
xfract.raw = fracs.x.split('/');
yfract.raw = fracs.y.split('/');
xfract.denom = xfract.raw[1];
xfract.numer = xfract.raw[0];
yfract.denom = yfract.raw[1];
yfract.numer = yfract.raw[0];
await this.dePage.getCanvasLine(name).then(async canvas => {
let action = await this.driver.actions();
let rect = await canvas.getRect();
let x = parseInt(rect.x);
let y = parseInt(rect.y);
let targetX = parseInt(((rect.width/xfract.denom) * xfract.numer) + x);
let targetY = parseInt(((rect.height/yfract.denom) * yfract.numer) + y);
await action.move({x: targetX, y: targetY, duration: 1000})
.doubleClick()
.perform();
await this.driver.sleep(200); // todo better wait - let graph update
});
}
async moveToVerticalFractionOfGraph(fraction){
let fract = fraction.split('/');
let denom = fract[1];
let numer = fract[0];
await this.dePage.getCanvasLine().then(async canvas => {
let action = await this.driver.actions();
let rect = await canvas.getRect();
let x = parseInt(rect.x);
let y = parseInt(rect.y);
let targetX = parseInt((rect.width/2) + x);
let targetY = parseInt(((rect.height/denom) * numer) + y);
await action.move({x: targetX, y: targetY, duration: 1000})
.perform();
await this.driver.sleep(200); // todo better wait - let graph update
});
}
async dragToVerticalFractionOfGraph(fraction){
let fract = fraction.split('/');
let denom = fract[1];
let numer = fract[0];
await this.dePage.getCanvasLine().then(async canvas => {
let action = await this.driver.actions();
let rect = await canvas.getRect();
let x = parseInt(rect.x);
let y = parseInt(rect.y);
let targetX = parseInt((rect.width/2) + x);
let targetY = parseInt(((rect.height/denom) * numer) + y);
await action.press()
.move({x: targetX, y: targetY, duration: 1000})
.release()
.perform();
await this.driver.sleep(200); // todo better wait - let graph update
});
}
async clickRefreshGraphButton() {
await this.dePage.getRefreshGraphButton().then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(500); //todo better wait
});
})
}
async clickRefreshDropdownPaused(){
await this.dePage.getRefreshDropdownPaused().then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(100); // todo better wait
});
});
}
async clickRefreshDropdownActive(){
await this.dePage.getRefreshDropdownActive().then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(100); // todo better wait
});
});
}
async selectRefreshDropdownItem(item){
await this.dePage.getRefreshDropdownItem(item).then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(100); // todo better wait
});
});
}
async clickAddQueryButton(){
await this.dePage.getAddQueryButton().then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(100); // todo better wait
});
});
}
async rightClickQueryTabTitle(title) {
await this.dePage.getQueryTabByName(title).then(async elem => {
let action = this.driver.actions();
await action.contextClick(elem).perform();
});
}
async clickQueryTabTitle(title) {
await this.dePage.getQueryTabByName(title).then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(100); // todo better wait
});
});
}
async selectQueryTabMenuItem(item){
await this.dePage.getQueryTabMenuItem(item).then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(100); // todo better wait
});
});
}
async setQueryTabName(name){
await this.dePage.getQueryTabNameInput().then(async elem => {
await this.driver.sleep(200);
//await elem.clear();
await elem.sendKeys(name);
});
}
async clickScriptEditorButton(){
await this.dePage.getScriptEditorButton().then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(100); // todo better wait
});
});
}
async pasteIntoScriptEditor(text){
await this.setMonacoEditorText(await this.dePage.getScriptMonacoEditor(), text);
}
async clickViewTypeDropdown(){
await this.clickAndWait(await this.dePage.getViewTypeDropdown());
}
async selectViewType(type){
await this.dePage.getViewType(type).then(async elem => {
await elem.click().then(async () => {
await this.driver.sleep(100); // todo better wait
});
});
}
async verifySingleStatTextVisible(){
await this.assertVisible(await this.dePage.getSingleStatText());
}
async clickViewRawDataToggle(){
await this.clickAndWait(await this.dePage.getRawDataToggle());
}
async verifyRawDataTableVisible(){
await this.assertVisible(await this.dePage.getRawDataTable());
}
async clickTimeRangeDropdown(){
await this.clickAndWait(await this.dePage.getTimeRangeDropdown());
}
async selectTimeRangeDropdownItem(item){
await this.clickAndWait(await this.dePage.getTimeRangeDropdownItem(item));
}
async searchFunction(funct){
await this.dePage.getFunctionSearchInput().then(async elem => {
//await elem.clear();
await elem.sendKeys(funct);
});
}
async selectFunctionFromList(funct){
await this.clickAndWait(await this.dePage.getSelectorListFunction(funct));
}
}

View File

@ -157,19 +157,19 @@ class scrapersSteps extends baseSteps{
});
}
async verifyNamedQueryResponseValues(queryName, username, bucket, values, field = '_value'){
let user = await influxUtils.getUser((username === 'DEFAULT') ? __defaultUser.username : username);
async verifyNamedQueryResponseValues(queryName, userName, bucketName, values, field = '_value'){
let user = await influxUtils.getUser(userName);
let query;
query = namedQueriesMap.get(queryName);
query = query.replace('[BUCKET]', bucket);
query = query.replace('[BUCKET]', (bucketName === 'DEFAULT') ? user.bucket : bucketName);
let resultsMapArr = await influxUtils.parseQueryResults(await influxUtils.query(user.orgid, query));
let results = await influxUtils.query(user.username, query);
let targetValues = values.split(',');
targetValues.forEach(async value => {
await expect(resultsMapArr.filter(rec =>
rec.get(field) === targetValues[0]
await expect(results.filter(rec =>
rec[field] === targetValues[0]
).length).to.be.above(0, `failed to locate record with value ${value} in field ${field}`);
});
}

View File

@ -208,6 +208,14 @@ class tokensSteps extends baseSteps{
}
}
async clickTokensSorterButton(){
await this.clickAndWait(await this.tknTab.getTokenSorterButton());
}
async clickTokensSorterItem(item){
await this.clickAndWait(await this.tknTab.getTokenSorterItem(item));
}
async clickTokensSortByName(){
await this.clickAndWait(await this.tknTab.getTokensSortByDescription());
}

View File

@ -74,8 +74,8 @@ class checkStatusHistorySteps extends influxSteps {
let last = await this.ckHistPage.getEventMarkerByIndex(markers.length);
//console.log("DEBUG first " + JSON.stringify(await first.getRect()));
//console.log("DEBUG last " + JSON.stringify(await last.getRect()));
await this.driver.executeScript('arguments[0].style.border=\'3px solid red\'', first);
await this.driver.executeScript('arguments[0].style.border=\'3px solid red\'', last);
//await this.driver.executeScript('arguments[0].style.border=\'3px solid red\'', first);
//await this.driver.executeScript('arguments[0].style.border=\'3px solid red\'', last);
await this.ckHistPage.getCanvasGraphContent().then(async canvas => {
//console.log("DEBUG canvas " + JSON.stringify(await canvas.getRect()));
let action = await this.driver.actions();

View File

@ -101,8 +101,8 @@ class templatesSteps extends baseSteps{
}
async verifyRESTTemplateDocumentExists(user,title){
let uzzer = await influxUtils.getUser(user);
let resp = await influxUtils.getDocTemplates(uzzer.orgid);
//let uzzer = await influxUtils.getUser(user);
let resp = await influxUtils.getDocTemplates(user);
let match = resp.documents.filter( doc => doc.meta.name === title);
expect(match.length).to.be.above(0);
}

View File

@ -3,39 +3,73 @@ const process = require('process');
const axios = require('axios');
const fs = require('fs');
const csvParseSync = require('csv-parse/lib/sync');
const {exec} = require('child_process');
const util = require('util');
const exec_prom = util.promisify(exec);
let active_config = require(__basedir + '/e2e.conf.json').active;
//let config = require(__basedir + '/e2e.conf.json')[active_config];
let setHeadless = false;
let newHeadless = false;
let selDocker = false;
let nowNano = new Date().getTime() * 1000000;
let intervalNano = 600 * 1000 * 1000000; //10 min in nanosecs
const {InfluxDB} = require('@influxdata/influxdb-client');
const { AuthorizationsAPI,
BucketsAPI,
ChecksAPI,
DashboardsAPI,
DocumentsAPI,
LabelsAPI,
OrgsAPI,
SetupAPI,
VariablesAPI} = require('@influxdata/influxdb-client-apis');
const active_config = require(__basedir + '/e2e.conf.json').active;
const config = require(__basedir + '/e2e.conf.json')[active_config];
const defaultUser = require(__basedir + '/e2e.conf.json').default_user;
const mil2Nano = 1000000;
axios.defaults.baseURL = `${config.protocol}://${config.host}:${config.port}`;
global.__config = config;
global.__defaultUser = defaultUser;
global.__users = { 'init': undefined };
global.__killLiveDataGen = false;
global.__liveDataGenRunning = false;
process.argv.slice(2).forEach((val) => {
let pair = val.split('=');
switch(pair[0]){
case 'headless': //overrides value in config file
config.headless = (pair[1] === 'true');
//config.headless = (pair[1] === 'true');
setHeadless = true;
newHeadless = (pair[1] === 'true');
break;
case 'sel_docker':
case 'selDocker':
config.sel_docker = (pair[1] === 'true');
//config.sel_docker = (pair[1] === 'true');
selDocker = (pair[1] === 'true');
break;
case 'activeConf':
case 'active_conf':
//config = require(__basedir + '/e2e.conf.json')[pair[1]];
active_config = pair[1];
}
});
const config = require(__basedir + '/e2e.conf.json')[active_config];
const defaultUser = config.default_user;
config.sel_docker = selDocker;
config.headless = setHeadless ? newHeadless : config.headless;
global.__config = config;
global.__defaultUser = defaultUser;
global.__users = { 'init': undefined };
global.__killLiveDataGen = false;
global.__liveDataGenRunning = false;
global.__reportedResetOnce = false;
console.log(config.headless ? 'running headless' : 'running headed');
console.log(config.sel_docker ? 'running for selenium in docker' : 'running for selenium standard');
console.log(`active configuration ${JSON.stringify(config)}`);
//Need to keep axios for calls to /debug/flush
axios.defaults.baseURL = `${config.influx_url}`;
/* Uncomment to debug axios
axios.interceptors.request.use(request => {
@ -50,24 +84,213 @@ axios.interceptors.response.use(response => {
*/
const flush = async () => {
// console.log('calling flush')
await axios.get('/debug/flush');
await axios.get('/debug/flush').catch(async error => {
console.log("DEBUG error " + JSON.stringify(error))
});
delete global.__users;
global.__users = { 'init': undefined };
};
// user { username: 'name', password: 'password', org; 'orgname', bucket: 'bucketname' }
const setupUser = async(user) => {
await axios.post('/api/v2/setup', user).then(resp => {
user.id = resp.data.user.id;
user.orgid = resp.data.org.id;
user.bucketid = resp.data.bucket.id;
putUser(user);
//console.log("DEBUG __users: " + JSON.stringify(__users, null, '\t'))
//console.log("DEBUG resp " + JSON.stringify(resp.data, null, '\t'))
const removeConfInDocker = async () => {
await exec_prom('docker exec influx2_solo rm /root/.influxdbv2/configs || true');
};
//for compatibility with old test style - until all are updated
const setupUser = async(newUser) => {
console.warn("WARNING: call to user old style start " + JSON.stringify(newUser));
if(newUser.username === 'ENV'){
await resolveUsernameFromEnv(newUser);
}
if(newUser.password === 'ENV'){
await resolvePasswordFromEnv(newUser);
}
await resolveUserTokenBeforeCreate(newUser);
await setupUserRest(newUser);
await putUser(newUser);
await __wdriver.sleep(1000);
await setUserOrgId(newUser);
};
const setUserOrgId = async(user) => {
//now grab the first org
let orgsAPI = new OrgsAPI(new InfluxDB({url: __config.influx_url, token: user.token, timeout: 20000}));
let orgs = await orgsAPI.getOrgs();
user.orgid = orgs.orgs[0].id;
};
// user { username: 'name', password: 'password', org; 'orgname', bucket: 'bucketname', token: 'optional_token' }
const setupNewUser = async(newUser) => {
let user = newUser.toUpperCase() === 'DEFAULT' ? __defaultUser : JSON.parse(newUser);
if(user.username === 'ENV'){
await resolveUsernameFromEnv(user);
}
if(user.password === 'ENV'){
await resolvePasswordFromEnv(user);
}
await resolveUserTokenBeforeCreate(user);
console.log(`--- preparing to setup user on ${__config.influx_url}`);
switch(__config.create_method.toUpperCase()){
case 'REST':
console.log(`--- Creating new User '${user.username}' over REST ---`);
await setupUserRest(user)
break;
case 'CLI_DOCKER':
console.log(`--- Creating new User '${user.username}' with CLI to docker container ${__config.docker_name} ---`);
await setupUserDockerCLI(user);
break;
case 'CLI':
console.log(`--- Creating new user '${user.username}' with CLI using influx CLI client at ${__config.influx_path} ---`);
await setupUserCLI(user);
break;
case "SKIP":
console.log(`Skipping creating user '${user.username}' on target deployment ` +
`at ${__config.host}. User should already exist there` );
break;
default:
throw `Unkown create user method ${__config.create_method}`
}
putUser(user);
await __wdriver.sleep(1000); //give db chance to update before continuing
await setUserOrgId(user);
};
const resolvePasswordFromEnv = async(user) => {
if(user.password.toUpperCase() === 'ENV'){
let envar = `${__config.config_id.toUpperCase()}_DEFAULT_USER_PASSWORD`;
user.password = process.env[envar]
}
};
const resolveUsernameFromEnv = async(user) => {
if(user.password.toUpperCase() === 'ENV'){
let envar = `${__config.config_id.toUpperCase()}_DEFAULT_USERNAME`;
user.username = process.env[envar]
}
};
const resolveUserTokenBeforeCreate = async(user) => {
if(typeof user.token === 'undefined'){
return;
}
if(user.token.toUpperCase() === 'ENV'){
let envar = `${__config.config_id.toUpperCase()}_DEFAULT_USER_TOKEN`;
user.token = process.env[envar]
}
};
const setupUserRest = async(user) => {
const setupAPI = new SetupAPI(new InfluxDB(__config.influx_url));
setupAPI.getSetup().then(async ({allowed}) => {
let body = {org: user.org, bucket: user.bucket, username: user.username, password: user.password };
if(user.token){
body.token = user.token;
}
if(allowed){
await setupAPI.postSetup({
body: body,
});
console.log(`--- Setup user ${JSON.stringify(user)} at ${__config.influx_url} success ---`)
}else{
console.error(`--- Failed to setup user ${JSON.stringify(user)} at ${__config.influx_url} ---`);
}
}).catch(async error => {
console.error(`\n--- Setup user ${JSON.stringify(user)} ended in ERROR ---`);
console.error(error)
});
};
const setupUserDockerCLI = async(user) => {
await removeConfInDocker();
let command = `docker exec ${__config.docker_name} /usr/bin/influx setup` +
` --host ${__config.influx_url}` +
` -o ${user.org} -b ${user.bucket} -u ${user.username} -p ${user.password}`;
if(typeof user.token !== 'undefined'){
command = command + ` -t ${user.token}`;
}
command = command + ' -f';
await exec_prom(command).catch(async error => {
console.warn(error);
});
};
const setupUserCLI = async(user) => {
let configsPath = `${process.env.HOME}/.influxdbv2/configs`;
if(await fs.existsSync(configsPath)){
await console.log(`--- removing configs ${configsPath} ---`);
await fs.unlink(configsPath, async err => {
if(err) throw err;
await console.log(`--- ${configsPath} deleted ---`);
})
}
let command = `${__config.influx_path} setup` +
` --host ${__config.influx_url}` +
` -o ${user.org} -b ${user.bucket} -u ${user.username} -p ${user.password}`;
if(typeof user.token !== 'undefined'){
command = command + ` -t ${user.token}`;
}
command = command + ' -f';
exec(command, async (error, stdout, stderr) => {
if(error){
await console.error("ERROR: " + error);
}
await console.log(stdout);
if(stderr){
await console.error(stderr)
}
});
};
//reserved for future solutions
const setupCloudUser = async(userName) => {
if(__config.config_id !== 'cloud'){
throw `Attempt to setup cloud user with config ${__config.config_id}`
}
if(userName.toUpperCase() !== 'DEFAULT'){
throw `${userName} not handled. Currently only DEFAULT cloud user in e2e.conf.json is handled.`
}
};
// user { username: 'name', password: 'password', org; 'orgname', bucket: 'bucketname' }
const putUser = (user) => {
if(!(user.username in __users)){
@ -89,7 +312,8 @@ const getUser = (name) => {
throw `"${name}" is not a key in global users`;
};
const signIn = async (username) => {
//TODO - replace or remove in usages
const signInAxios = async (username) => {
let user = getUser(username);
return await axios.post('/api/v2/signin', '', {auth: {username: user.username, password: user.password}}).then(async resp => {
@ -108,54 +332,62 @@ const signIn = async (username) => {
};
//TODO - replace or remove in usages
const endSession = async() => {
delete axios.defaults.headers.common['Cookie'];
};
let nowNano = new Date().getTime() * 1000000;
let intervalNano = 600 * 1000 * 1000000; //10 min in nanosecs
const writeData = async (org, //string
bucket, //string
const writeData = async (userName, //string
lines = ['testmeas value=300 ' + (nowNano - (3 * intervalNano)),
'testmeas value=200 ' + (nowNano - (2 * intervalNano)),
'testmeas value=100 ' + (nowNano - intervalNano)],
chunkSize = 100) => {
'testmeas value=100 ' + (nowNano - intervalNano)]) => {
let chunk = [];
let chunkCt = 0;
let user = await getUser(userName);
while(chunkCt < lines.length){
chunk = ((chunkCt + chunkSize) <= lines.length) ?
lines.slice(chunkCt, chunkCt + chunkSize - 1) :
lines.slice(chunkCt, chunkCt + (lines.length % chunkSize));
await axios.post('/api/v2/write?org=' + org + '&bucket=' + bucket, chunk.join('\n') ).then(() => {
// console.log(resp.status)
}).catch( err => {
console.log(err);
});
const writeAPI = await new InfluxDB({url: __config.influx_url, token: user.token})
.getWriteApi(user.org, user.bucket, 'ns');
chunkCt += chunkSize;
chunk = [];
}
await writeAPI.writeRecords(lines);
await writeAPI.close().catch(e => {
console.error(`ERROR: closing write connection: ${e}`);
throw e;
})
};
const query = async(orgID, //string
const query = async(userName, //string
query // string
) => {
return await axios({method: 'post',
url: '/api/v2/query?orgID=' + orgID,
data: {'query': query} }).then(async response => {
return response.data;
}).catch(async err => {
console.log('CAUGHT ERROR: ' + err);
let user = await getUser(userName);
const queryApi = await new InfluxDB({url: __config.influx_url, token: user.token})
.getQueryApi(user.org);
//need to return array of strings as result
let result = [];
return await new Promise((resolve,reject) => {
queryApi.queryRows(query, {
next(row, tableMeta) {
const o = tableMeta.toObject(row);
result.push(o);
},
error(error) {
reject(error)
},
complete() {
resolve(result);
},
});
}).catch(async error => {
console.error('Caught Error on Query: ' + error);
throw error;
});
};
// TODO - verify usages with changes using client API
//Parse query result string to Array[Map()] of column items
const parseQueryResults = async(results) => {
let resultsArr = results.split('\r\n,');
@ -180,146 +412,127 @@ const parseQueryResults = async(results) => {
return resultsMapArr;
};
// TODO - add retentionRules or retention policy rp
//{"name":"ASDF","retentionRules":[],"orgID":"727d19908f30184f","organization":"qa"}
const createBucket = async(orgId, // String
orgName, //String
bucketName, //String
) => {
//throw "createBuctket() not implemented";
return await axios({
method: 'post',
url: '/api/v2/buckets',
data: { 'name': bucketName, 'orgID': orgId, 'organization': orgName }
}).then(async response => {
return response.data;
}).catch(async err => {
console.log('influxUtils.createBucket - Error ' + err);
});
bucketAPI = new BucketsAPI(new InfluxDB({url: __config.influx_url, token: __defaultUser.token, timeout: 20000}));
await bucketAPI.postBuckets({body: {name: bucketName, orgID: orgId}});
};
//TODO - create cell and view to attach to dashboard
const createDashboard = async(name, orgId) => {
return await axios.post('/api/v2/dashboards', { name, orgId }).then(resp => {
return resp.data;
}).catch(err => {
console.log('ERROR: ' + err);
throw(err); // rethrow it to cucumber
const dbdsAPI = new DashboardsAPI(new InfluxDB({url: __config.influx_url, token: __defaultUser.token, timeout: 20000}));
await dbdsAPI.postDashboards({body: {name: name, orgID: orgId}}).catch(async error => {
console.log('--- Error Creating dashboard ---');
console.error(error);
throw error;
});
};
const getDashboards = async() => {
return await axios.get('/api/v2/dashboards').then(resp => {
return resp.data;
}).catch(err => {
console.log('ERROR: ' + err);
throw(err);
});
const getDashboards = async(userName) => {
let user = getUser(userName);
const dbdsAPI = new DashboardsAPI(new InfluxDB({url: __config.influx_url, token: user.token, timeout: 20000}));
return await dbdsAPI.getDashboards();
};
const getAuthorizations = async(userName) => {
let user = getUser(userName);
let authsAPI = new AuthorizationsAPI(new InfluxDB({url: __config.influx_url, token: user.token, timeout: 20000}));
return await authsAPI.getAuthorizations();
};
// http://localhost:9999/api/v2/labels
// {"orgID":"8576cb897e0b4ce9","name":"MyLabel","properties":{"description":"","color":"#7CE490"}}
const createLabel = async(orgId,
const createLabel = async(userName,
labelName,
labelDescr,
labelColor ) =>{
return await axios({
method: 'post',
url: '/api/v2/labels',
data: { 'orgId': orgId, 'name': labelName,
'properties': { 'description': labelDescr, 'color': labelColor }}
}).then(resp => {
return resp.data;
}).catch(err => {
console.log('ERROR: ' + err);
throw(err);
let user = getUser(userName);
const lblAPI = new LabelsAPI(new InfluxDB({url: __config.influx_url, token: user.token, timeout: 20000}));
let lblCreateReq = {body: {name: labelName, orgID: user.orgid,
properties: { description: labelDescr, color: labelColor }}};
await lblAPI.postLabels(lblCreateReq).catch(async error => {
console.log('--- Error Creating label ---');
console.error(error);
throw error;
});
};
const createVariable = async(userName, name, type, values, selected = null ) => {
const createVariable = async(orgId, name, type, values, selected = null ) => {
let user = getUser(userName);
let varAPI = new VariablesAPI(new InfluxDB({url: __config.influx_url, token: user.token, timeout: 20000}));
let parseValues = JSON.parse(values);
let reSel = selected === null ? selected : JSON.parse(selected);
return await axios({
method: 'post',
url: '/api/v2/variables',
data: {
'orgId': orgId,
'name': name,
'selected': reSel,
'arguments': {
'type': type,
'values': parseValues
}
}
}).then(resp => {
return resp.data;
}).catch(err => {
console.log('ERROR: ' + err );
throw(err);
return await varAPI.postVariables({body: {name: name,
orgID: user.orgid,
arguments: {
type: type,
values: parseValues
},
selected: reSel
}
})
};
const getDocTemplates = async(orgId) => {
const getDocTemplates = async(userName) => {
return await axios({
method: 'get',
url: `/api/v2/documents/templates?orgID=${orgId}`
}).then(resp => {
return resp.data;
}).catch(err => {
throw(err);
});
let user = getUser(userName);
let docsAPI = new DocumentsAPI(new InfluxDB({url: __config.influx_url, token: user.token, timeout: 20000, }));
return await docsAPI.getDocumentsTemplates({orgID: user.orgid});
};
const createTemplateFromFile = async(filepath, orgID) => {
const createTemplateFromFile = async(userName, filepath) => {
let user = getUser(userName);
let docsAPI = new DocumentsAPI(new InfluxDB({url: __config.influx_url, token: user.token, timeout: 20000}));
let content = await readFileToBuffer(process.cwd() + '/' + filepath);
let newTemplate = JSON.parse(content);
newTemplate.orgID = orgID;
return await axios({
method: 'POST',
url: '/api/v2/documents/templates',
data: newTemplate
}).then(resp => {
return resp.data;
}).catch(err => {
throw(err);
});
newTemplate.orgID = user.orgid;
docsAPI.postDocumentsTemplates({ body: newTemplate});
};
const createAlertCheckFromFile = async(filepath, orgID) => {
const createAlertCheckFromFile = async(userName, filepath) => {
let user = getUser(userName);
let content = await readFileToBuffer(process.cwd() + '/' + filepath);
//let re = /\\/g;
//content = content.replace(/\\/g, "\\\\\\");
///console.log("DEBUG content \n" + content + "\n");
//let newCheck = JSON.parse('{"id":null,"type":"threshold","status":"active","activeStatus":"active","name":"ASDF","query":{"name":"","text":"from(bucket: \\"qa\\")\\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\\n |> filter(fn: (r) => r[\\"_measurement\\"] == \\"test\\")\\n |> filter(fn: (r) => r[\\"_field\\"] == \\"val\\")\\n |> aggregateWindow(every: 1m, fn: mean)\\n |> yield(name: \\"mean\\")","editMode":"builder","builderConfig":{"buckets":["qa"],"tags":[{"key":"_measurement","values":["test"],"aggregateFunctionType":"filter"},{"key":"_field","values":["val"],"aggregateFunctionType":"filter"},{"key":"gen","values":[],"aggregateFunctionType":"filter"}],"functions":[{"name":"mean"}],"aggregateWindow":{"period":"1m"}},"hidden":false},"orgID":"05a6a2d5ea213000","labels":[],"every":"1m","offset":"0s","statusMessageTemplate":"Check: ${ r._check_name } is: ${ r._level }","tags":[],"thresholds":[{"type":"greater","value":7.5,"level":"CRIT"}]}');
let newCheck = JSON.parse(content);
newCheck.orgID = orgID;
newCheck.orgID = user.orgid;
return await axios({
method: 'POST',
url: '/api/v2/checks',
data: newCheck
}).then(resp => {
return resp.data;
}).catch(err => {
console.error("DEBUG err " + JSON.stringify(err));
throw(err);
});
let chkAPI = new ChecksAPI(new InfluxDB({url: __config.influx_url, token: user.token, timeout: 20000}));
chkAPI.createCheck({body: newCheck});
};
const writeLineProtocolData = async (user, def) => {
const writeLineProtocolData = async (userName, def) => {
let define = JSON.parse(def);
@ -329,7 +542,6 @@ const writeLineProtocolData = async (user, def) => {
let intervals = await getIntervalMillis(define.points, define.start);
let startMillis = nowMillis - intervals.full;
// let samples = await genPoints(define.algo, define.points);
let samples;
if(define.data === undefined) {
samples = await genPoints(define.algo, define.points);
@ -347,7 +559,7 @@ const writeLineProtocolData = async (user, def) => {
}
}
await writeData(user.org, user.bucket, dataPoints);
await writeData(userName, dataPoints);
};
// sample def : { "points": 10, "measurement":"level", "start": "-60h", "algo": "hydro", "prec": "sec"}
@ -419,7 +631,7 @@ const genPoints = async (algo, count, data = null) => {
const getIntervalMillis = async(count, start) => {
let time = start.slice(0, -1);
let fullInterval = 0;
let pointInterval = 0;
let pointInterval;
switch(start[start.length - 1]){
case 'd': //days
fullInterval = Math.abs(parseInt(time)) * 24 * 60000 * 60;
@ -536,7 +748,7 @@ const genDicoValues = async(count,data) => {
const readFileToBuffer = async function(filepath) {
return await fs.readFileSync(filepath, 'utf-8'); //, async (err) => {
return await fs.readFileSync(filepath, 'utf-8');
};
const removeFileIfExists = async function(filepath){
@ -630,7 +842,7 @@ const dataGenProcess = async function(def = {pulse: 333, model: 'count10'}){
break;
}
//console.log("PULSE " + val);
await writeData(__defaultUser.org,__defaultUser.bucket, [
await writeData(__defaultUser.username, [
`test,gen=gen val=${val} ${current * mil2Nano}`
]);
__liveDataGenRunning = true;
@ -641,11 +853,11 @@ const dataGenProcess = async function(def = {pulse: 333, model: 'count10'}){
__liveDataGenRunning = false;
};
const startLiveDataGen = function(def){
const startLiveDataGen = async function(def){
if(!__liveDataGenRunning) {
console.log(`Starting live generator with ${JSON.stringify(def)} ${(new Date()).toISOString()}`);
__killLiveDataGen = false;
dataGenProcess(JSON.parse(def));
await dataGenProcess(JSON.parse(def));
}else{
console.log(`Live Data Generator already running ${(new Date()).toISOString()}`);
}
@ -661,7 +873,7 @@ module.exports = { flush,
setupUser,
putUser,
getUser,
signIn,
signInAxios,
endSession,
writeData,
createDashboard,
@ -681,8 +893,11 @@ module.exports = { flush,
readFileToBuffer,
readCSV,
createTemplateFromFile,
getAuthorizations,
removeConfInDocker,
removeFileIfExists,
removeFilesByRegex,
setupNewUser,
startLiveDataGen,
stopLiveDataGen,
fileExists,