chore(e2e): refactor and stablize tests (#18531)
parent
42ef78d0c5
commit
72a415de51
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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\']';
|
||||
|
|
|
@ -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;
|
||||
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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\')]';
|
||||
|
|
|
@ -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(){
|
||||
|
|
|
@ -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\']'
|
||||
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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']`));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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(){
|
||||
|
|
|
@ -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();
|
||||
});
|
|
@ -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)}`);
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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}`);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue