Chore: remove wrapping of cy in the e2e object (#74650)

* remove cy. wrapping as e2e().

* make trace-view-scrolling more stable and remove waits

* improve stability more
This commit is contained in:
Ashley Harrison 2023-09-11 11:20:54 +01:00 committed by GitHub
parent 7718a67b77
commit 247d91be2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 518 additions and 622 deletions

View File

@ -39,9 +39,7 @@ Cypress.Commands.add('checkHealthRetryable', function (fn: Function, retryCount:
function provisionAzureMonitorDatasources(datasources: AzureMonitorProvision[]) {
const datasource = datasources[0].datasources[0];
e2e()
.intercept(/subscriptions/)
.as('subscriptions');
cy.intercept(/subscriptions/).as('subscriptions');
e2e.flows.addDataSource({
type: 'Azure Monitor',
@ -164,32 +162,28 @@ e2e.scenario({
// This variable will be set in CI
const CI = e2e.env('CI');
if (CI) {
e2e()
.readFile('outputs.json')
.then((outputs) => {
provisionAzureMonitorDatasources([
{
datasources: [
{
jsonData: {
cloudName: 'Azure',
tenantId: outputs.tenantId,
clientId: outputs.clientId,
},
secureJsonData: { clientSecret: outputs.clientSecret },
cy.readFile('outputs.json').then((outputs) => {
provisionAzureMonitorDatasources([
{
datasources: [
{
jsonData: {
cloudName: 'Azure',
tenantId: outputs.tenantId,
clientId: outputs.clientId,
},
],
},
]);
});
secureJsonData: { clientSecret: outputs.clientSecret },
},
],
},
]);
});
} else {
e2e()
.readFile(provisioningPath)
.then((azMonitorProvision: string) => {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const yaml = load(azMonitorProvision) as AzureMonitorProvision;
provisionAzureMonitorDatasources([yaml]);
});
cy.readFile(provisioningPath).then((azMonitorProvision: string) => {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const yaml = load(azMonitorProvision) as AzureMonitorProvision;
provisionAzureMonitorDatasources([yaml]);
});
}
e2e.setScenarioContext({ addedDataSources: [] });
},
@ -217,9 +211,9 @@ e2e.scenario({
.type(storageAcctName)
.wait(500)
.type('{enter}');
e2e().contains(storageAcctName).click();
cy.contains(storageAcctName).click();
e2eSelectors.queryEditor.resourcePicker.apply.button().click();
e2e().contains('microsoft.storage/storageaccounts');
cy.contains('microsoft.storage/storageaccounts');
e2eSelectors.queryEditor.metricsQueryEditor.metricName.input().find('input').type('Used capacity{enter}');
},
timeout: 10000,
@ -237,7 +231,7 @@ e2e.scenario({
.type(logAnalyticsName)
.wait(500)
.type('{enter}');
e2e().contains(logAnalyticsName).click();
cy.contains(logAnalyticsName).click();
e2eSelectors.queryEditor.resourcePicker.apply.button().click();
e2e.components.CodeEditor.container().type('AzureDiagnostics');
e2eSelectors.queryEditor.logsQueryEditor.formatSelection.input().type('Time series{enter}');
@ -250,7 +244,7 @@ e2e.scenario({
visitDashboardAtStart: false,
queriesForm: () => {
e2eSelectors.queryEditor.header.select().find('input').type('Azure Resource Graph{enter}');
e2e().wait(1000); // Need to wait for code editor to completely load
cy.wait(1000); // Need to wait for code editor to completely load
e2eSelectors.queryEditor.argsQueryEditor.subscriptions
.input()
.find('[aria-label="select-clear-value"]')
@ -276,9 +270,9 @@ e2e.scenario({
.type(applicationInsightsName)
.wait(500)
.type('{enter}');
e2e().contains(applicationInsightsName).click();
cy.contains(applicationInsightsName).click();
e2eSelectors.queryEditor.resourcePicker.apply.button().click();
e2e().wait(10000);
cy.wait(10000);
e2eSelectors.queryEditor.logsQueryEditor.formatSelection.input().type('Trace{enter}');
},
timeout: 10000,
@ -370,11 +364,11 @@ e2e.scenario({
e2e.components.DataSourcePicker.inputV2().click().type(`${dataSourceName}{enter}`);
e2eSelectors.queryEditor.resourcePicker.select.button().click();
e2eSelectors.queryEditor.resourcePicker.search.input().type(storageAcctName);
e2e().contains(storageAcctName).click();
cy.contains(storageAcctName).click();
e2eSelectors.queryEditor.resourcePicker.apply.button().click();
e2e().contains('microsoft.storage/storageaccounts');
cy.contains('microsoft.storage/storageaccounts');
e2eSelectors.queryEditor.metricsQueryEditor.metricName.input().find('input').type('Transactions{enter}');
e2e().get('table').contains('text').parent().find('input').click().type('Transactions (number){enter}');
cy.get('table').contains('text').parent().find('input').click().type('Transactions (number){enter}');
e2e.components.PageToolbar.item('Go Back').click();
e2e.flows.addPanel({
dataSourceName,
@ -382,9 +376,9 @@ e2e.scenario({
queriesForm: () => {
e2eSelectors.queryEditor.resourcePicker.select.button().click();
e2eSelectors.queryEditor.resourcePicker.search.input().type(storageAcctName);
e2e().contains(storageAcctName).click();
cy.contains(storageAcctName).click();
e2eSelectors.queryEditor.resourcePicker.apply.button().click();
e2e().contains('microsoft.storage/storageaccounts');
cy.contains('microsoft.storage/storageaccounts');
e2eSelectors.queryEditor.metricsQueryEditor.metricName.input().find('input').type('Used capacity{enter}');
},
});

View File

@ -41,7 +41,7 @@ describe('Repeating a panel horizontally', () => {
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('1').click();
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('3').click();
// blur the dropdown
e2e().get('body').click();
cy.get('body').click();
const panelsShown = ['Panel Title 1', 'Panel Title 3'];
const panelsNotShown = ['Panel Title 2'];

View File

@ -42,7 +42,7 @@ describe('Repeating a panel vertically', () => {
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('1').click();
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('3').click();
// blur the dropdown
e2e().get('body').click();
cy.get('body').click();
const panelsShown = ['Panel Title 1', 'Panel Title 3'];
const panelsNotShown = ['Panel Title 2'];

View File

@ -37,7 +37,7 @@ describe('Repeating empty rows', () => {
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('1').click();
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('3').click();
// blur the dropdown
e2e().get('body').click();
cy.get('body').click();
const rowsShown = ['Row title 1', 'Row title 3'];
const rowsNotShown = ['Row title 2'];

View File

@ -1,5 +1,3 @@
import { selectors } from '@grafana/e2e-selectors';
import { e2e } from '../utils';
import { makeNewDashboardRequestBody } from './utils/makeDashboard';
@ -20,79 +18,73 @@ describe.skip('Dashboard browse (nested)', () => {
// Add root folders
for (let i = 0; i < NUM_ROOT_FOLDERS; i++) {
e2e()
.request({
method: 'POST',
url: '/api/folders',
body: {
title: `Root folder ${i.toString().padStart(2, '0')}`,
},
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => {
folderUIDsToCleanUp.push(response.body.uid);
});
}
// Add root dashboards
for (let i = 0; i < NUM_ROOT_DASHBOARDS; i++) {
e2e()
.request({
method: 'POST',
url: '/api/dashboards/db',
body: makeNewDashboardRequestBody(`Root dashboard ${i.toString().padStart(2, '0')}`),
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => {
dashboardUIDsToCleanUp.push(response.body.uid);
});
}
// Add folder with children
e2e()
.request({
cy.request({
method: 'POST',
url: '/api/folders',
body: {
title: 'A root folder with children',
title: `Root folder ${i.toString().padStart(2, '0')}`,
},
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => {
const folderUid = response.body.uid;
folderUIDsToCleanUp.push(folderUid);
// Add nested folders
for (let i = 0; i < NUM_NESTED_FOLDERS; i++) {
e2e().request({
method: 'POST',
url: '/api/folders',
body: {
title: `Nested folder ${i.toString().padStart(2, '0')}`,
parentUid: folderUid,
},
headers: {
'Content-Type': 'application/json',
},
});
}
// Add nested dashboards
for (let i = 0; i < NUM_NESTED_DASHBOARDS; i++) {
e2e().request({
method: 'POST',
url: '/api/dashboards/db',
body: makeNewDashboardRequestBody(`Nested dashboard ${i.toString().padStart(2, '0')}`, folderUid),
headers: {
'Content-Type': 'application/json',
},
});
}
}).then((response) => {
folderUIDsToCleanUp.push(response.body.uid);
});
}
// Add root dashboards
for (let i = 0; i < NUM_ROOT_DASHBOARDS; i++) {
cy.request({
method: 'POST',
url: '/api/dashboards/db',
body: makeNewDashboardRequestBody(`Root dashboard ${i.toString().padStart(2, '0')}`),
headers: {
'Content-Type': 'application/json',
},
}).then((response) => {
dashboardUIDsToCleanUp.push(response.body.uid);
});
}
// Add folder with children
cy.request({
method: 'POST',
url: '/api/folders',
body: {
title: 'A root folder with children',
},
headers: {
'Content-Type': 'application/json',
},
}).then((response) => {
const folderUid = response.body.uid;
folderUIDsToCleanUp.push(folderUid);
// Add nested folders
for (let i = 0; i < NUM_NESTED_FOLDERS; i++) {
cy.request({
method: 'POST',
url: '/api/folders',
body: {
title: `Nested folder ${i.toString().padStart(2, '0')}`,
parentUid: folderUid,
},
headers: {
'Content-Type': 'application/json',
},
});
}
// Add nested dashboards
for (let i = 0; i < NUM_NESTED_DASHBOARDS; i++) {
cy.request({
method: 'POST',
url: '/api/dashboards/db',
body: makeNewDashboardRequestBody(`Nested dashboard ${i.toString().padStart(2, '0')}`, folderUid),
headers: {
'Content-Type': 'application/json',
},
});
}
});
});
// Remove nested folder structure
@ -107,7 +99,7 @@ describe.skip('Dashboard browse (nested)', () => {
}
// Clean up root folders (cascading delete will remove any nested folders and dashboards)
for (const folderUID of folderUIDsToCleanUp) {
e2e().request({
cy.request({
method: 'DELETE',
url: `/api/folders/${folderUID}`,
qs: {
@ -120,29 +112,29 @@ describe.skip('Dashboard browse (nested)', () => {
it('pagination works correctly for folders and root', () => {
e2e.pages.Dashboards.visit();
e2e().contains('A root folder with children').should('be.visible');
cy.contains('A root folder with children').should('be.visible');
// Expand A root folder with children
e2e().get('[aria-label="Expand folder A root folder with children"]').click();
e2e().contains('Nested folder 00').should('be.visible');
cy.get('[aria-label="Expand folder A root folder with children"]').click();
cy.contains('Nested folder 00').should('be.visible');
// Scroll the page and check visibility of next set of items
e2e().get(`[data-testid="${selectors.pages.BrowseDashboards.table.body}"] > div`).scrollTo(0, 1700);
e2e().contains('Nested folder 59').should('be.visible');
e2e().contains('Nested dashboard 00').should('be.visible');
e2e.pages.BrowseDashboards.table.body().find('> div').scrollTo(0, 1700);
cy.contains('Nested folder 59').should('be.visible');
cy.contains('Nested dashboard 00').should('be.visible');
// Scroll the page and check visibility of next set of items
e2e().get(`[data-testid="${selectors.pages.BrowseDashboards.table.body}"] > div`).scrollTo(0, 3800);
e2e().contains('Nested dashboard 59').should('be.visible');
e2e().contains('Root folder 00').should('be.visible');
e2e.pages.BrowseDashboards.table.body().find('> div').scrollTo(0, 3800);
cy.contains('Nested dashboard 59').should('be.visible');
cy.contains('Root folder 00').should('be.visible');
// Scroll the page and check visibility of next set of items
e2e().get(`[data-testid="${selectors.pages.BrowseDashboards.table.body}"] > div`).scrollTo(0, 5900);
e2e().contains('Root folder 59').should('be.visible');
e2e().contains('Root dashboard 00').should('be.visible');
e2e.pages.BrowseDashboards.table.body().find('> div').scrollTo(0, 5900);
cy.contains('Root folder 59').should('be.visible');
cy.contains('Root dashboard 00').should('be.visible');
// Scroll the page and check visibility of next set of items
e2e().get(`[data-testid="${selectors.pages.BrowseDashboards.table.body}"] > div`).scrollTo(0, 8000);
e2e().contains('Root dashboard 59').should('be.visible');
e2e.pages.BrowseDashboards.table.body().find('> div').scrollTo(0, 8000);
cy.contains('Root dashboard 59').should('be.visible');
});
});

View File

@ -8,13 +8,11 @@ e2e.scenario({
skipScenario: false,
scenario: () => {
// Opening a dashboard without template variables
e2e()
.intercept({
pathname: '/api/ds/query',
})
.as('query');
cy.intercept({
pathname: '/api/ds/query',
}).as('query');
e2e.flows.openDashboard({ uid: 'ZqZnVvFZz' });
e2e().wait('@query');
cy.wait('@query');
// Open sharing modal
e2e.pages.ShareDashboardModal.shareButton().click();
@ -41,9 +39,9 @@ e2e.scenario({
e2e.pages.ShareDashboardModal.PublicDashboard.CreateButton().should('be.enabled');
// Create public dashboard
e2e().intercept('POST', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('save');
cy.intercept('POST', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('save');
e2e.pages.ShareDashboardModal.PublicDashboard.CreateButton().click();
e2e().wait('@save');
cy.wait('@save');
// These elements shouldn't be rendered after creating public dashboard
e2e.pages.ShareDashboardModal.PublicDashboard.WillBePublicCheckbox().should('not.exist');
@ -73,14 +71,12 @@ e2e.scenario({
skipScenario: false,
scenario: () => {
// Opening a dashboard without template variables
e2e()
.intercept({
method: 'POST',
pathname: '/api/ds/query',
})
.as('query');
cy.intercept({
method: 'POST',
pathname: '/api/ds/query',
}).as('query');
e2e.flows.openDashboard({ uid: 'ZqZnVvFZz' });
e2e().wait('@query');
cy.wait('@query');
// Tag indicating a dashboard is public
e2e.pages.Dashboard.DashNav.publicDashboardTag().should('exist');
@ -89,9 +85,9 @@ e2e.scenario({
e2e.pages.ShareDashboardModal.shareButton().click();
// Select public dashboards tab
e2e().intercept('GET', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('query-public-dashboard');
cy.intercept('GET', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('query-public-dashboard');
e2e.pages.ShareDashboardModal.PublicDashboard.Tab().click();
e2e().wait('@query-public-dashboard');
cy.wait('@query-public-dashboard');
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput().should('exist');
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlButton().should('exist');
@ -108,8 +104,7 @@ e2e.scenario({
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput()
.invoke('val')
.then((url) => {
e2e()
.clearCookies()
cy.clearCookies()
.request(getPublicDashboardAPIUrl(String(url)))
.then((resp) => {
expect(resp.status).to.eq(200);
@ -126,49 +121,44 @@ e2e.scenario({
skipScenario: false,
scenario: () => {
// Opening a dashboard without template variables
e2e()
.intercept({
method: 'POST',
pathname: '/api/ds/query',
})
.as('query');
cy.intercept({
method: 'POST',
pathname: '/api/ds/query',
}).as('query');
e2e.flows.openDashboard({ uid: 'ZqZnVvFZz' });
e2e().wait('@query');
cy.wait('@query');
// Open sharing modal
e2e.pages.ShareDashboardModal.shareButton().click();
// Select public dashboards tab
e2e().intercept('GET', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('query-public-dashboard');
cy.intercept('GET', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('query-public-dashboard');
e2e.pages.ShareDashboardModal.PublicDashboard.Tab().click();
e2e().wait('@query-public-dashboard');
cy.wait('@query-public-dashboard');
// save url before disabling public dashboard
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput()
.invoke('val')
.then((text) => e2e().wrap(text).as('url'));
.then((text) => cy.wrap(text).as('url'));
// Save public dashboard
e2e().intercept('PATCH', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards/*').as('update');
cy.intercept('PATCH', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards/*').as('update');
// Switch off enabling toggle
e2e.pages.ShareDashboardModal.PublicDashboard.PauseSwitch().should('be.enabled').click({ force: true });
e2e().wait('@update');
cy.wait('@update');
// Url should be hidden
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput().should('be.disabled');
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlButton().should('be.disabled');
// Make a request to public dashboards api endpoint without authentication
e2e()
.get('@url')
.then((url) => {
e2e()
.clearCookies()
.request({ url: getPublicDashboardAPIUrl(String(url)), failOnStatusCode: false })
.then((resp) => {
expect(resp.status).to.eq(403);
});
});
cy.get('@url').then((url) => {
cy.clearCookies()
.request({ url: getPublicDashboardAPIUrl(String(url)), failOnStatusCode: false })
.then((resp) => {
expect(resp.status).to.eq(403);
});
});
},
});

View File

@ -40,8 +40,7 @@ e2e.scenario({
`Example: from=now-6h&to=now`,
];
e2e()
.get('.markdown-html li')
cy.get('.markdown-html li')
.should('have.length', 26)
.each((element) => {
items.push(element.text());
@ -53,8 +52,10 @@ e2e.scenario({
});
// Check link interpolation is working correctly
e2e()
.contains('a', 'Example: from=now-6h&to=now')
.should('have.attr', 'href', 'https://example.com/?from=now-6h&to=now');
cy.contains('a', 'Example: from=now-6h&to=now').should(
'have.attr',
'href',
'https://example.com/?from=now-6h&to=now'
);
},
});

View File

@ -95,7 +95,7 @@ e2e.scenario({
uid: 'd41dbaa2-a39e-4536-ab2b-caca52f1a9c8',
});
e2e().intercept('/api/ds/query*').as('dataQuery');
cy.intercept('/api/ds/query*').as('dataQuery');
// Switch to Browser timezone
e2e.flows.setTimeRange({
@ -104,12 +104,12 @@ e2e.scenario({
zone: 'Browser',
});
// Need to wait for 2 calls as there's 2 panels
e2e().wait(['@dataQuery', '@dataQuery']);
cy.wait(['@dataQuery', '@dataQuery']);
e2e.components.Panels.Panel.title('Panel with relative time override')
.should('be.visible')
.within(() => {
e2e().contains('[role="row"]', '00:00:00').should('be.visible');
cy.contains('[role="row"]', '00:00:00').should('be.visible');
});
// Today so far, still in Browser timezone
@ -118,18 +118,18 @@ e2e.scenario({
to: 'now',
});
// Need to wait for 2 calls as there's 2 panels
e2e().wait(['@dataQuery', '@dataQuery']);
cy.wait(['@dataQuery', '@dataQuery']);
e2e.components.Panels.Panel.title('Panel with relative time override')
.should('be.visible')
.within(() => {
e2e().contains('[role="row"]', '00:00:00').should('be.visible');
cy.contains('[role="row"]', '00:00:00').should('be.visible');
});
e2e.components.Panels.Panel.title('Panel in timezone')
.should('be.visible')
.within(() => {
e2e().contains('[role="row"]', '00:00:00').should('be.visible');
cy.contains('[role="row"]', '00:00:00').should('be.visible');
});
// Test Tokyo timezone
@ -139,12 +139,12 @@ e2e.scenario({
zone: 'Asia/Tokyo',
});
// Need to wait for 2 calls as there's 2 panels
e2e().wait(['@dataQuery', '@dataQuery']);
cy.wait(['@dataQuery', '@dataQuery']);
e2e.components.Panels.Panel.title('Panel with relative time override')
.should('be.visible')
.within(() => {
e2e().contains('[role="row"]', '00:00:00').should('be.visible');
cy.contains('[role="row"]', '00:00:00').should('be.visible');
});
// Today so far, still in Tokyo timezone
@ -153,18 +153,18 @@ e2e.scenario({
to: 'now',
});
// Need to wait for 2 calls as there's 2 panels
e2e().wait(['@dataQuery', '@dataQuery']);
cy.wait(['@dataQuery', '@dataQuery']);
e2e.components.Panels.Panel.title('Panel with relative time override')
.should('be.visible')
.within(() => {
e2e().contains('[role="row"]', '00:00:00').should('be.visible');
cy.contains('[role="row"]', '00:00:00').should('be.visible');
});
e2e.components.Panels.Panel.title('Panel in timezone')
.should('be.visible')
.within(() => {
e2e().contains('[role="row"]', '00:00:00').should('be.visible');
cy.contains('[role="row"]', '00:00:00').should('be.visible');
});
// Test LA timezone
@ -174,12 +174,12 @@ e2e.scenario({
zone: 'America/Los_Angeles',
});
// Need to wait for 2 calls as there's 2 panels
e2e().wait(['@dataQuery', '@dataQuery']);
cy.wait(['@dataQuery', '@dataQuery']);
e2e.components.Panels.Panel.title('Panel with relative time override')
.should('be.visible')
.within(() => {
e2e().contains('[role="row"]', '00:00:00').should('be.visible');
cy.contains('[role="row"]', '00:00:00').should('be.visible');
});
// Today so far, still in LA timezone
@ -188,18 +188,18 @@ e2e.scenario({
to: 'now',
});
// Need to wait for 2 calls as there's 2 panels
e2e().wait(['@dataQuery', '@dataQuery']);
cy.wait(['@dataQuery', '@dataQuery']);
e2e.components.Panels.Panel.title('Panel with relative time override')
.should('be.visible')
.within(() => {
e2e().contains('[role="row"]', '00:00:00').should('be.visible');
cy.contains('[role="row"]', '00:00:00').should('be.visible');
});
e2e.components.Panels.Panel.title('Panel in timezone')
.should('be.visible')
.within(() => {
e2e().contains('[role="row"]', '00:00:00').should('be.visible');
cy.contains('[role="row"]', '00:00:00').should('be.visible');
});
},
});

View File

@ -25,7 +25,7 @@ e2e.scenario({
// Assert that the calendar shows 08 and 09 and 10 as selected days
e2e.components.TimePicker.openButton().click();
e2e.components.TimePicker.calendar.openButton().first().click();
e2e().get('.react-calendar__tile--active, .react-calendar__tile--hasActive').should('have.length', 3);
cy.get('.react-calendar__tile--active, .react-calendar__tile--hasActive').should('have.length', 3);
},
});
@ -49,6 +49,6 @@ e2e.scenario({
// Assert that the calendar shows 08 and 09 and 10 as selected days
e2e.components.TimePicker.openButton().click();
e2e.components.TimePicker.calendar.openButton().first().click();
e2e().get('.react-calendar__tile--active, .react-calendar__tile--hasActive').should('have.length', 3);
cy.get('.react-calendar__tile--active, .react-calendar__tile--hasActive').should('have.length', 3);
},
});

View File

@ -6,14 +6,12 @@ describe('Variables - Load options from Url', () => {
it('default options should be correct', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST });
e2e()
.intercept({
method: 'POST',
pathname: '/api/ds/query*',
})
.as('query');
cy.intercept({
method: 'POST',
pathname: '/api/ds/query*',
}).as('query');
e2e().wait('@query');
cy.wait('@query');
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('A').should('be.visible').click();
@ -58,14 +56,12 @@ describe('Variables - Load options from Url', () => {
it('options set in url should load correct options', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&var-datacenter=B&var-server=BB&var-pod=BBB` });
e2e()
.intercept({
method: 'POST',
pathname: '/api/ds/query',
})
.as('query');
cy.intercept({
method: 'POST',
pathname: '/api/ds/query',
}).as('query');
e2e().wait('@query');
cy.wait('@query');
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('B').should('be.visible').click();
@ -110,7 +106,7 @@ describe('Variables - Load options from Url', () => {
it('options set in url that do not exist should load correct options', () => {
e2e.flows.login('admin', 'admin');
// @ts-ignore some typing issue
e2e().on('uncaught:exception', (err) => {
cy.on('uncaught:exception', (err) => {
if (err.stack?.indexOf("Couldn't find any field of type string in the results.") !== -1) {
// return false to prevent the error from
// failing this test
@ -121,14 +117,12 @@ describe('Variables - Load options from Url', () => {
});
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&var-datacenter=X` });
e2e()
.intercept({
method: 'POST',
pathname: '/api/ds/query',
})
.as('query');
cy.intercept({
method: 'POST',
pathname: '/api/ds/query',
}).as('query');
e2e().wait('@query');
cy.wait('@query');
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('X').should('be.visible').click();

View File

@ -7,13 +7,13 @@ describe('Variables - Constant', () => {
it('can add a new constant variable', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` });
e2e().contains(DASHBOARD_NAME).should('be.visible');
cy.contains(DASHBOARD_NAME).should('be.visible');
// Create a new "Constant" variable
e2e.components.CallToActionCard.buttonV2('Add variable').click();
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
e2e().get('input').type('Constant{enter}');
cy.get('input').type('Constant{enter}');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type('VariableUnderTest').blur();
e2e.pages.Dashboard.Settings.Variables.Edit.ConstantVariable.constantOptionsQueryInputV2().type('pesto').blur();
@ -27,7 +27,7 @@ describe('Variables - Constant', () => {
e2e.components.RefreshPicker.runButtonV2().click();
// Assert it was rendered
e2e().get('.markdown-html').should('include.text', 'VariableUnderTest: pesto');
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: pesto');
// Assert the variable is not visible in the dashboard nav
e2e.pages.Dashboard.SubMenu.submenuItemLabels('Variable under test').should('not.exist');

View File

@ -5,7 +5,7 @@ const DASHBOARD_NAME = 'Test variable output';
function fillInCustomVariable(name: string, label: string, value: string) {
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
e2e().get('input').type('Custom{enter}');
cy.get('input').type('Custom{enter}');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type(name).blur();
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type(label).blur();
@ -23,7 +23,7 @@ describe('Variables - Custom', () => {
it('can add a custom template variable', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` });
e2e().contains(DASHBOARD_NAME).should('be.visible');
cy.contains(DASHBOARD_NAME).should('be.visible');
// Create a new "Custom" variable
e2e.components.CallToActionCard.buttonV2('Add variable').click();
@ -37,18 +37,18 @@ describe('Variables - Custom', () => {
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('two').click();
// Assert it was rendered
e2e().get('.markdown-html').should('include.text', 'VariableUnderTest: two');
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: two');
});
it('can add a custom template variable with labels', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` });
e2e().contains(DASHBOARD_NAME).should('be.visible');
cy.contains(DASHBOARD_NAME).should('be.visible');
// Create a new "Custom" variable
e2e.components.CallToActionCard.buttonV2('Add variable').click();
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
e2e().get('input').type('Custom{enter}');
cy.get('input').type('Custom{enter}');
});
// Set its name, label, and content
@ -62,6 +62,6 @@ describe('Variables - Custom', () => {
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('Two').click();
// Assert it was rendered
e2e().get('.markdown-html').should('include.text', 'VariableUnderTest: 2');
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: 2');
});
});

View File

@ -7,12 +7,12 @@ describe('Variables - Datasource', () => {
it('can add a new datasource variable', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` });
e2e().contains(DASHBOARD_NAME).should('be.visible');
cy.contains(DASHBOARD_NAME).should('be.visible');
// Create a new "Datasource" variable
e2e.components.CallToActionCard.buttonV2('Add variable').click();
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
e2e().get('input').type('Data source{enter}');
cy.get('input').type('Data source{enter}');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type('VariableUnderTest').blur();
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type('Variable under test').blur();
@ -20,7 +20,7 @@ describe('Variables - Datasource', () => {
// If this is failing, but sure to check there are Prometheus datasources named "gdev-prometheus" and "gdev-slow-prometheus"
// Or, just update is to match some gdev datasources to test with :)
e2e.pages.Dashboard.Settings.Variables.Edit.DatasourceVariable.datasourceSelect().within(() => {
e2e().get('input').type('Prometheus{enter}');
cy.get('input').type('Prometheus{enter}');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption()
.eq(0)
@ -38,7 +38,7 @@ describe('Variables - Datasource', () => {
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('gdev-slow-prometheus').click();
// Assert it was rendered
e2e().get('.markdown-html').should('include.text', 'VariableUnderTest: gdev-slow-prometheus-uid');
e2e().get('.markdown-html').should('include.text', 'VariableUnderTestText: gdev-slow-prometheus');
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: gdev-slow-prometheus-uid');
cy.get('.markdown-html').should('include.text', 'VariableUnderTestText: gdev-slow-prometheus');
});
});

View File

@ -14,12 +14,12 @@ describe('Variables - Interval', () => {
it('can add a new interval variable', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` });
e2e().contains(DASHBOARD_NAME).should('be.visible');
cy.contains(DASHBOARD_NAME).should('be.visible');
// Create a new "Interval" variable
e2e.components.CallToActionCard.buttonV2('Add variable').click();
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
e2e().get('input').type('Interval{enter}');
cy.get('input').type('Interval{enter}');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type('VariableUnderTest').blur();
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type('Variable under test').blur();
@ -40,6 +40,6 @@ describe('Variables - Interval', () => {
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('1h30m').click();
// Assert it was rendered
e2e().get('.markdown-html').should('include.text', 'VariableUnderTest: 1h30m');
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: 1h30m');
});
});

View File

@ -7,7 +7,7 @@ describe('Variables - Query - Add variable', () => {
it('query variable should be default and default fields should be correct', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` });
e2e().contains(DASHBOARD_NAME).should('be.visible');
cy.contains(DASHBOARD_NAME).should('be.visible');
e2e.pages.Dashboard.Settings.Variables.List.newButton().should('be.visible').click();
@ -28,22 +28,21 @@ describe('Variables - Query - Add variable', () => {
expect(input.attr('placeholder')).equals('Label name');
expect(input.val()).equals('');
});
e2e()
.get('[placeholder="Descriptive text"]')
cy.get('[placeholder="Descriptive text"]')
.should('be.visible')
.within((input) => {
expect(input.attr('placeholder')).equals('Descriptive text');
expect(input.val()).equals('');
});
e2e().get('label').contains('Show on dashboard').should('be.visible');
cy.get('label').contains('Show on dashboard').should('be.visible');
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsDataSourceSelect()
.get('input[placeholder="gdev-testdata"]')
.scrollIntoView()
.should('be.visible');
e2e().get('label').contains('Refresh').scrollIntoView().should('be.visible');
e2e().get('label').contains('On dashboard load').scrollIntoView().should('be.visible');
cy.get('label').contains('Refresh').scrollIntoView().should('be.visible');
cy.get('label').contains('On dashboard load').scrollIntoView().should('be.visible');
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsRegExInputV2()
.should('be.visible')
@ -58,17 +57,13 @@ describe('Variables - Query - Add variable', () => {
e2e.components.Select.singleValue().should('have.text', 'Disabled');
});
e2e()
.contains('label', 'Multi-value')
.within(() => {
e2e().get('input[type="checkbox"]').should('not.be.checked');
});
cy.contains('label', 'Multi-value').within(() => {
cy.get('input[type="checkbox"]').should('not.be.checked');
});
e2e()
.contains('label', 'Include All option')
.within(() => {
e2e().get('input[type="checkbox"]').should('not.be.checked');
});
cy.contains('label', 'Include All option').within(() => {
cy.get('input[type="checkbox"]').should('not.be.checked');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().should('not.exist');
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsCustomAllInputV2().should('not.exist');
@ -77,7 +72,7 @@ describe('Variables - Query - Add variable', () => {
it('adding a single value query variable', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` });
e2e().contains(DASHBOARD_NAME).should('be.visible');
cy.contains(DASHBOARD_NAME).should('be.visible');
e2e.pages.Dashboard.Settings.Variables.List.newButton().should('be.visible').click();
@ -86,7 +81,7 @@ describe('Variables - Query - Add variable', () => {
.clear()
.type('a label');
e2e().get('[placeholder="Descriptive text"]').should('be.visible').clear().type('a description');
cy.get('[placeholder="Descriptive text"]').should('be.visible').clear().type('a description');
e2e.components.DataSourcePicker.container().should('be.visible').type('gdev-testdata{enter}');
@ -111,7 +106,7 @@ describe('Variables - Query - Add variable', () => {
.should('have.length', 4)
.eq(3)
.within(() => {
e2e().get('.variable-link-wrapper').should('be.visible').click();
cy.get('.variable-link-wrapper').should('be.visible').click();
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownDropDown()
.should('be.visible')
.within(() => {
@ -125,7 +120,7 @@ describe('Variables - Query - Add variable', () => {
it('adding a multi value query variable', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` });
e2e().contains(DASHBOARD_NAME).should('be.visible');
cy.contains(DASHBOARD_NAME).should('be.visible');
e2e.pages.Dashboard.Settings.Variables.List.newButton().should('be.visible').click();
@ -134,7 +129,7 @@ describe('Variables - Query - Add variable', () => {
.clear()
.type('a label');
e2e().get('[placeholder="Descriptive text"]').should('be.visible').clear().type('a description');
cy.get('[placeholder="Descriptive text"]').should('be.visible').clear().type('a description');
e2e.components.DataSourcePicker.container().type('gdev-testdata{enter}');
@ -148,17 +143,13 @@ describe('Variables - Query - Add variable', () => {
.type('/.*C.*/')
.blur();
e2e()
.contains('label', 'Multi-value')
.within(() => {
e2e().get('input[type="checkbox"]').click({ force: true }).should('be.checked');
});
cy.contains('label', 'Multi-value').within(() => {
cy.get('input[type="checkbox"]').click({ force: true }).should('be.checked');
});
e2e()
.contains('label', 'Include All option')
.within(() => {
e2e().get('input[type="checkbox"]').click({ force: true }).should('be.checked');
});
cy.contains('label', 'Include All option').within(() => {
cy.get('input[type="checkbox"]').click({ force: true }).should('be.checked');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsCustomAllInputV2().within((input) => {
expect(input.attr('placeholder')).equals('blank = auto');
@ -176,7 +167,7 @@ describe('Variables - Query - Add variable', () => {
.should('have.length', 4)
.eq(3)
.within(() => {
e2e().get('.variable-link-wrapper').should('be.visible').click();
cy.get('.variable-link-wrapper').should('be.visible').click();
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownDropDown()
.should('be.visible')
.within(() => {

View File

@ -7,13 +7,13 @@ describe('Variables - Text box', () => {
it('can add a new text box variable', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` });
e2e().contains(DASHBOARD_NAME).should('be.visible');
cy.contains(DASHBOARD_NAME).should('be.visible');
// Create a new "text box" variable
e2e.components.CallToActionCard.buttonV2('Add variable').click();
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
e2e().get('input').type('Text box{enter}');
cy.get('input').type('Text box{enter}');
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type('VariableUnderTest').blur();
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type('Variable under test').blur();
@ -24,9 +24,9 @@ describe('Variables - Text box', () => {
// Navigate back to the homepage and change the selected variable value
e2e.pages.Dashboard.Settings.Variables.Edit.General.submitButton().click();
e2e.pages.Dashboard.Settings.Actions.close().click();
e2e().get('#var-VariableUnderTest').clear().type('dog-cat').blur();
cy.get('#var-VariableUnderTest').clear().type('dog-cat').blur();
// Assert it was rendered
e2e().get('.markdown-html').should('include.text', 'VariableUnderTest: dog-cat');
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: dog-cat');
});
});

View File

@ -52,20 +52,18 @@ describe('Variables - Set options from ui', () => {
it('adding a value that is not part of dependents options should add the new values dependant options', () => {
e2e.flows.login('admin', 'admin');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&var-datacenter=A&var-server=AA&var-pod=AAA` });
e2e()
.intercept({
pathname: '/api/ds/query',
})
.as('query');
cy.intercept({
pathname: '/api/ds/query',
}).as('query');
e2e().wait('@query');
cy.wait('@query');
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('A').should('be.visible').click();
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('B').should('be.visible').click();
e2e.components.NavToolbar.container().click();
e2e().wait('@query');
cy.wait('@query');
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('A + B').scrollIntoView().should('be.visible');
@ -106,16 +104,16 @@ describe('Variables - Set options from ui', () => {
e2e.flows.openDashboard({
uid: `${PAGE_UNDER_TEST}?orgId=1&var-datacenter=A&var-datacenter=B&var-server=AA&var-server=BB&var-pod=AAA&var-pod=BBB`,
});
e2e().intercept({ pathname: '/api/ds/query' }).as('query');
cy.intercept({ pathname: '/api/ds/query' }).as('query');
e2e().wait('@query');
cy.wait('@query');
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('A + B').should('be.visible').click();
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('A').should('be.visible').click();
e2e.components.NavToolbar.container().click();
e2e().wait('@query');
cy.wait('@query');
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('B').scrollIntoView().should('be.visible');

View File

@ -7,23 +7,19 @@ e2e.scenario({
addScenarioDashBoard: false,
skipScenario: false,
scenario: () => {
e2e()
.intercept({
method: 'GET',
url: '/api/search?tag=templating&limit=100',
})
.as('tagsTemplatingSearch');
e2e()
.intercept({
method: 'GET',
url: '/api/search?tag=demo&limit=100',
})
.as('tagsDemoSearch');
cy.intercept({
method: 'GET',
url: '/api/search?tag=templating&limit=100',
}).as('tagsTemplatingSearch');
cy.intercept({
method: 'GET',
url: '/api/search?tag=demo&limit=100',
}).as('tagsDemoSearch');
e2e.flows.openDashboard({ uid: 'yBCC3aKGk' });
// waiting for network requests first
e2e().wait(['@tagsTemplatingSearch', '@tagsDemoSearch']);
cy.wait(['@tagsTemplatingSearch', '@tagsDemoSearch']);
const verifyLinks = (variableValue: string) => {
e2e.components.DashboardLinks.link()

View File

@ -32,19 +32,17 @@ describe.skip('TextBox - change query scenarios', function () {
saveDashboard(false);
e2e()
.get<string>('@dashuid')
.then((dashuid) => {
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
cy.get<string>('@dashuid').then((dashuid) => {
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
e2e.flows.openDashboard({ uid: dashuid });
e2e.flows.openDashboard({ uid: dashuid });
e2e().wait('@load-dash');
cy.wait('@load-dash');
validateTextboxAndMarkup('default value');
validateTextboxAndMarkup('default value');
validateVariable('changed value');
});
validateVariable('changed value');
});
});
it('when changing the query value and saving current as default should change query value', function () {
@ -58,19 +56,17 @@ describe.skip('TextBox - change query scenarios', function () {
saveDashboard(true);
e2e()
.get<string>('@dashuid')
.then((dashuid) => {
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
cy.get<string>('@dashuid').then((dashuid) => {
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
e2e.flows.openDashboard({ uid: dashuid });
e2e.flows.openDashboard({ uid: dashuid });
e2e().wait('@load-dash');
cy.wait('@load-dash');
validateTextboxAndMarkup('changed value');
validateTextboxAndMarkup('changed value');
validateVariable('changed value');
});
validateVariable('changed value');
});
});
});
@ -84,18 +80,16 @@ describe.skip('TextBox - change picker value scenarios', function () {
saveDashboard(false);
e2e()
.get<string>('@dashuid')
.then((dashuid) => {
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
cy.get<string>('@dashuid').then((dashuid) => {
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
e2e.flows.openDashboard({ uid: dashuid });
e2e.flows.openDashboard({ uid: dashuid });
e2e().wait('@load-dash');
cy.wait('@load-dash');
validateTextboxAndMarkup('default value');
validateVariable('default value');
});
validateTextboxAndMarkup('default value');
validateVariable('default value');
});
});
it('when changing the input value and saving current as default should change query value', function () {
@ -107,44 +101,36 @@ describe.skip('TextBox - change picker value scenarios', function () {
saveDashboard(true);
e2e()
.get<string>('@dashuid')
.then((dashuid) => {
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
cy.get<string>('@dashuid').then((dashuid) => {
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
e2e.flows.openDashboard({ uid: dashuid });
e2e.flows.openDashboard({ uid: dashuid });
e2e().wait('@load-dash');
cy.wait('@load-dash');
validateTextboxAndMarkup('changed value');
validateVariable('changed value');
});
validateTextboxAndMarkup('changed value');
validateVariable('changed value');
});
});
});
function copyExistingDashboard() {
e2e.flows.login('admin', 'admin');
e2e()
.intercept({
method: 'GET',
url: '/api/search?query=&type=dash-folder&permission=Edit',
})
.as('dash-settings');
e2e()
.intercept({
method: 'POST',
url: '/api/dashboards/db/',
})
.as('save-dash');
e2e()
.intercept({
method: 'GET',
url: /\/api\/dashboards\/uid\/(?!AejrN1AMz)\w+/,
})
.as('load-dash');
cy.intercept({
method: 'GET',
url: '/api/search?query=&type=dash-folder&permission=Edit',
}).as('dash-settings');
cy.intercept({
method: 'POST',
url: '/api/dashboards/db/',
}).as('save-dash');
cy.intercept({
method: 'GET',
url: /\/api\/dashboards\/uid\/(?!AejrN1AMz)\w+/,
}).as('load-dash');
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}/templating-textbox-e2e-scenarios?orgId=1&editview=settings` });
e2e().wait('@dash-settings');
cy.wait('@dash-settings');
e2e.pages.Dashboard.Settings.General.saveAsDashBoard().should('be.visible').click();
@ -152,19 +138,17 @@ function copyExistingDashboard() {
e2e.pages.SaveDashboardAsModal.save().should('be.visible').click();
e2e().wait('@save-dash');
e2e().wait('@load-dash');
cy.wait('@save-dash');
cy.wait('@load-dash');
e2e.pages.Dashboard.SubMenu.submenuItem().should('be.visible');
e2e()
.location()
.then((loc) => {
const dashuid = /\/d\/(\w+)\//.exec(loc.href)![1];
e2e().wrap(dashuid).as('dashuid');
});
cy.location().then((loc) => {
const dashuid = /\/d\/(\w+)\//.exec(loc.href)![1];
cy.wrap(dashuid).as('dashuid');
});
e2e().wait(500);
cy.wait(500);
}
function saveDashboard(saveVariables: boolean) {
@ -176,7 +160,7 @@ function saveDashboard(saveVariables: boolean) {
e2e.pages.SaveDashboardModal.save().should('be.visible').click();
e2e().wait('@save-dash');
cy.wait('@save-dash');
}
function validateTextboxAndMarkup(value: string) {
@ -184,13 +168,13 @@ function validateTextboxAndMarkup(value: string) {
.should('be.visible')
.within(() => {
e2e.pages.Dashboard.SubMenu.submenuItemLabels('text').should('be.visible');
e2e().get('input').should('be.visible').should('have.value', value);
cy.get('input').should('be.visible').should('have.value', value);
});
e2e.components.Panels.Visualization.Text.container()
.should('be.visible')
.within(() => {
e2e().get('h1').should('be.visible').should('have.text', `variable: ${value}`);
cy.get('h1').should('be.visible').should('have.text', `variable: ${value}`);
});
}
@ -211,8 +195,7 @@ function changeTextBoxInput() {
e2e.pages.Dashboard.SubMenu.submenuItem()
.should('be.visible')
.within(() => {
e2e()
.get('input')
cy.get('input')
.should('be.visible')
.should('have.value', 'default value')
.clear()
@ -220,11 +203,9 @@ function changeTextBoxInput() {
.type('{enter}');
});
e2e()
.location()
.should((loc) => {
expect(loc.search).to.contain('var-text=changed%20value');
});
cy.location().should((loc) => {
expect(loc.search).to.contain('var-text=changed%20value');
});
}
function changeQueryInput() {

View File

@ -9,13 +9,11 @@ e2e.scenario({
addScenarioDashBoard: false,
skipScenario: false,
scenario: () => {
e2e()
.intercept({
pathname: '/api/ds/query',
})
.as('query');
cy.intercept({
pathname: '/api/ds/query',
}).as('query');
e2e.flows.openDashboard({ uid: 'TkZXxlNG3' });
e2e().wait('@query');
cy.wait('@query');
e2e.flows.openPanelMenuItem(e2e.flows.PanelMenuItems.Edit, PANEL_UNDER_TEST);
@ -71,7 +69,7 @@ e2e.scenario({
e2e.components.PanelEditor.toggleVizOptions().click();
e2e.components.PanelEditor.OptionsPane.content().should('not.exist');
e2e().wait(100);
cy.wait(100);
// open options pane
e2e.components.PanelEditor.toggleVizOptions().should('be.visible').click();

View File

@ -46,7 +46,7 @@ e2e.scenario({
.first()
.should('be.visible')
.within(() => {
e2e().get('input[id*="test-data-scenario-select-"]').eq(0).should('be.visible').click();
cy.get('input[id*="test-data-scenario-select-"]').eq(0).should('be.visible').click();
});
cy.contains('CSV Metric Values').scrollIntoView().should('be.visible').eq(0).click();

View File

@ -9,14 +9,14 @@ export const smokeTestScenario = {
loginViaApi: false,
scenario: () => {
// wait for time to be set to account for any layout shift
e2e().contains('2020-01-01 00:00:00 to 2020-01-01 06:00:00').should('be.visible');
cy.contains('2020-01-01 00:00:00 to 2020-01-01 06:00:00').should('be.visible');
e2e.components.PageToolbar.itemButton('Add button').click();
e2e.components.PageToolbar.itemButton('Add new visualization menu item').click();
e2e.components.DataSource.TestData.QueryTab.scenarioSelectContainer()
.should('be.visible')
.within(() => {
e2e().get('input[id*="test-data-scenario-select-"]').should('be.visible').click();
cy.get('input[id*="test-data-scenario-select-"]').should('be.visible').click();
});
cy.contains('CSV Metric Values').scrollIntoView().should('be.visible').click();

View File

@ -23,24 +23,22 @@ e2e.scenario({
e2e.pages.AddDashboard.itemButton('Add new visualization menu item').should('be.visible');
e2e.pages.AddDashboard.itemButton('Add new visualization menu item').click();
e2e()
.window()
.then((win: Cypress.AUTWindow & { grafanaBootData: GrafanaBootConfig['bootData'] }) => {
// Loop through every panel type and ensure no crash
Object.entries(win.grafanaBootData.settings.panels).forEach(([_, panel]) => {
// TODO: Remove Flame Graph check as part of addressing #66803
if (!panel.hideFromList && panel.state !== 'deprecated') {
e2e.components.PanelEditor.toggleVizPicker().click();
e2e.components.PluginVisualization.item(panel.name).scrollIntoView().should('be.visible').click();
cy.window().then((win: Cypress.AUTWindow & { grafanaBootData: GrafanaBootConfig['bootData'] }) => {
// Loop through every panel type and ensure no crash
Object.entries(win.grafanaBootData.settings.panels).forEach(([_, panel]) => {
// TODO: Remove Flame Graph check as part of addressing #66803
if (!panel.hideFromList && panel.state !== 'deprecated') {
e2e.components.PanelEditor.toggleVizPicker().click();
e2e.components.PluginVisualization.item(panel.name).scrollIntoView().should('be.visible').click();
// Wait for panel to load (TODO: Better way to do this?)
cy.wait(500);
// Wait for panel to load (TODO: Better way to do this?)
cy.wait(500);
e2e.components.PanelEditor.toggleVizPicker().should((e) => expect(e).to.contain(panel.name));
// TODO: Come up with better check / better failure messaging to clearly indicate which panel failed
cy.contains('An unexpected error happened').should('not.exist');
}
});
e2e.components.PanelEditor.toggleVizPicker().should((e) => expect(e).to.contain(panel.name));
// TODO: Come up with better check / better failure messaging to clearly indicate which panel failed
cy.contains('An unexpected error happened').should('not.exist');
}
});
});
},
});

View File

@ -11,7 +11,7 @@ describe('MySQL datasource', () => {
it('code editor autocomplete should handle table name escaping/quoting', () => {
e2e.flows.login('admin', 'admin');
e2e().intercept(
cy.intercept(
'POST',
{
pathname: '/api/ds/query',
@ -40,26 +40,26 @@ describe('MySQL datasource', () => {
e2e.components.DataSourcePicker.container().should('be.visible').type('gdev-mysql{enter}');
e2e().get("label[for^='option-code']").should('be.visible').click();
e2e().get('textarea').type('S{downArrow}{enter}');
e2e().wait('@tables');
e2e().get('.suggest-widget').contains(tableNameWithSpecialCharacter).should('be.visible');
e2e().get('textarea').type('{enter}');
e2e().get('textarea').should('have.value', `SELECT FROM grafana.\`${tableNameWithSpecialCharacter}\``);
cy.get("label[for^='option-code']").should('be.visible').click();
cy.get('textarea').type('S{downArrow}{enter}');
cy.wait('@tables');
cy.get('.suggest-widget').contains(tableNameWithSpecialCharacter).should('be.visible');
cy.get('textarea').type('{enter}');
cy.get('textarea').should('have.value', `SELECT FROM grafana.\`${tableNameWithSpecialCharacter}\``);
const deleteTimes = new Array(tableNameWithSpecialCharacter.length + 2).fill(
'{backspace}',
0,
tableNameWithSpecialCharacter.length + 2
);
e2e().get('textarea').type(deleteTimes.join(''));
cy.get('textarea').type(deleteTimes.join(''));
e2e().get('textarea').type('{command}i');
e2e().get('.suggest-widget').contains(tableNameWithSpecialCharacter).should('be.visible');
e2e().get('textarea').type('S{downArrow}{enter}');
e2e().get('textarea').should('have.value', `SELECT FROM grafana.${normalTableName}`);
cy.get('textarea').type('{command}i');
cy.get('.suggest-widget').contains(tableNameWithSpecialCharacter).should('be.visible');
cy.get('textarea').type('S{downArrow}{enter}');
cy.get('textarea').should('have.value', `SELECT FROM grafana.${normalTableName}`);
e2e().get('textarea').type('.');
e2e().get('.suggest-widget').contains('No suggestions.').should('be.visible');
cy.get('textarea').type('.');
cy.get('.suggest-widget').contains('No suggestions.').should('be.visible');
});
});

View File

@ -125,7 +125,7 @@ export const addDashboard = (config?: Partial<AddDashboardConfig>) => {
const { annotations, timeRange, title, variables } = fullConfig;
e2e().logToConsole('Adding dashboard with title:', title);
cy.logToConsole('Adding dashboard with title:', title);
e2e.pages.AddDashboard.visit();
@ -146,9 +146,9 @@ export const addDashboard = (config?: Partial<AddDashboardConfig>) => {
e2e.flows.assertSuccessNotification();
e2e.pages.AddDashboard.itemButton('Create new panel button').should('be.visible');
e2e().logToConsole('Added dashboard with title:', title);
cy.logToConsole('Added dashboard with title:', title);
return e2e()
return cy
.url()
.should('contain', '/d/')
.then((url: string) => {
@ -161,7 +161,7 @@ export const addDashboard = (config?: Partial<AddDashboardConfig>) => {
});
// @todo remove `wrap` when possible
return e2e().wrap(
return cy.wrap(
{
config: fullConfig,
uid,
@ -278,7 +278,7 @@ const addVariable = (config: PartialAddVariableConfig, isFirst: boolean): AddVar
}
// Avoid flakiness
e2e().focused().blur();
cy.focused().blur();
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption()
.should('exist')

View File

@ -45,12 +45,10 @@ export const addDataSource = (config?: Partial<AddDataSourceConfig>) => {
} = fullConfig;
if (awaitHealth) {
e2e()
.intercept(/health/)
.as('health');
cy.intercept(/health/).as('health');
}
e2e().logToConsole('Adding data source with name:', name);
cy.logToConsole('Adding data source with name:', name);
e2e.pages.AddDataSource.visit();
e2e.pages.AddDataSource.dataSourcePluginsV2(type)
.scrollIntoView()
@ -61,23 +59,22 @@ export const addDataSource = (config?: Partial<AddDataSourceConfig>) => {
e2e.pages.DataSource.name().type(name);
if (basicAuth) {
e2e().contains('label', 'Basic auth').scrollIntoView().click();
e2e()
.contains('.gf-form-group', 'Basic Auth Details')
cy.contains('label', 'Basic auth').scrollIntoView().click();
cy.contains('.gf-form-group', 'Basic Auth Details')
.should('be.visible')
.scrollIntoView()
.within(() => {
if (basicAuthUser) {
e2e().get('[placeholder=user]').type(basicAuthUser);
cy.get('[placeholder=user]').type(basicAuthUser);
}
if (basicAuthPassword) {
e2e().get('[placeholder=Password]').type(basicAuthPassword);
cy.get('[placeholder=Password]').type(basicAuthPassword);
}
});
}
if (skipTlsVerify) {
e2e().contains('label', 'Skip TLS Verify').scrollIntoView().click();
cy.contains('label', 'Skip TLS Verify').scrollIntoView().click();
}
form();
@ -85,7 +82,7 @@ export const addDataSource = (config?: Partial<AddDataSourceConfig>) => {
e2e.pages.DataSource.saveAndTest().click();
if (awaitHealth) {
e2e().wait('@health', { timeout: timeout ?? e2e.config().defaultCommandTimeout });
cy.wait('@health', { timeout: timeout ?? e2e.config().defaultCommandTimeout });
}
// use the timeout passed in if it exists, otherwise, continue to use the default
@ -94,23 +91,21 @@ export const addDataSource = (config?: Partial<AddDataSourceConfig>) => {
.contains(expectedAlertMessage, {
timeout: timeout ?? e2e.config().defaultCommandTimeout,
});
e2e().logToConsole('Added data source with name:', name);
cy.logToConsole('Added data source with name:', name);
return e2e()
.url()
.then(() => {
e2e.getScenarioContext().then(({ addedDataSources }: any) => {
e2e.setScenarioContext({
addedDataSources: [...addedDataSources, { name } as DeleteDataSourceConfig],
});
return cy.url().then(() => {
e2e.getScenarioContext().then(({ addedDataSources }: any) => {
e2e.setScenarioContext({
addedDataSources: [...addedDataSources, { name } as DeleteDataSourceConfig],
});
// @todo remove `wrap` when possible
return e2e().wrap(
{
config: fullConfig,
},
{ log: false }
);
});
// @todo remove `wrap` when possible
return cy.wrap(
{
config: fullConfig,
},
{ log: false }
);
});
};

View File

@ -109,14 +109,14 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC
// @todo alias '/**/*.js*' as '@pluginModule' when possible: https://github.com/cypress-io/cypress/issues/1296
e2e().intercept(chartData.method, chartData.route).as('chartData');
cy.intercept(chartData.method, chartData.route).as('chartData');
if (dataSourceName) {
e2e.components.DataSourcePicker.container().click().type(`${dataSourceName}{downArrow}{enter}`);
}
// @todo instead wait for '@pluginModule' if not already loaded
e2e().wait(2000);
cy.wait(2000);
// `panelTitle` is needed to edit the panel, and unlikely to have its value changed at that point
const changeTitle = panelTitle && !isEdit;
@ -130,7 +130,7 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC
e2e.components.PluginVisualization.item(visualizationName).scrollIntoView().click();
// @todo wait for '@pluginModule' if not a core visualization and not already loaded
e2e().wait(2000);
cy.wait(2000);
}
} else {
// Consistently closed
@ -142,21 +142,21 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC
// Wait for a possible complex visualization to render (or something related, as this isn't necessary on the dashboard page)
// Can't assert that its HTML changed because a new query could produce the same results
e2e().wait(1000);
cy.wait(1000);
}
// @todo enable when plugins have this implemented
//e2e.components.QueryEditorRow.actionButton('Disable/enable query').click();
//e2e().wait('@chartData');
//cy.wait('@chartData');
//e2e.components.Panels.Panel.containerByTitle(panelTitle).find('.panel-content').contains('No data');
//e2e.components.QueryEditorRow.actionButton('Disable/enable query').click();
//e2e().wait('@chartData');
//cy.wait('@chartData');
// Avoid annotations flakiness
e2e.components.RefreshPicker.runButtonV2().first().click({ force: true });
// Wait for RxJS
e2e().wait(timeout ?? e2e.config().defaultCommandTimeout);
cy.wait(timeout ?? e2e.config().defaultCommandTimeout);
if (matchScreenshot) {
let visualization;
@ -164,11 +164,11 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC
visualization = e2e.components.Panels.Panel.containerByTitle(panelTitle).find('.panel-content');
visualization.scrollIntoView().screenshot(screenshotName);
e2e().compareScreenshots(screenshotName);
cy.compareScreenshots(screenshotName);
}
// @todo remove `wrap` when possible
return e2e().wrap({ config: fullConfig }, { log: false });
return cy.wrap({ config: fullConfig }, { log: false });
});
// @todo this actually returns type `Cypress.Chainable`

View File

@ -8,7 +8,7 @@ export interface DeleteDashboardConfig {
}
export const deleteDashboard = ({ quick = false, title, uid }: DeleteDashboardConfig) => {
e2e().logToConsole('Deleting dashboard with uid:', uid);
cy.logToConsole('Deleting dashboard with uid:', uid);
if (quick) {
quickDelete(uid);
@ -16,7 +16,7 @@ export const deleteDashboard = ({ quick = false, title, uid }: DeleteDashboardCo
uiDelete(uid, title);
}
e2e().logToConsole('Deleted dashboard with uid:', uid);
cy.logToConsole('Deleted dashboard with uid:', uid);
e2e.getScenarioContext().then(({ addedDashboards }: any) => {
e2e.setScenarioContext({
@ -28,7 +28,7 @@ export const deleteDashboard = ({ quick = false, title, uid }: DeleteDashboardCo
};
const quickDelete = (uid: string) => {
e2e().request('DELETE', fromBaseUrl(`/api/dashboards/uid/${uid}`));
cy.request('DELETE', fromBaseUrl(`/api/dashboards/uid/${uid}`));
};
const uiDelete = (uid: string, title: string) => {
@ -42,10 +42,8 @@ const uiDelete = (uid: string, title: string) => {
// @todo replace `e2e.pages.Dashboards.dashboards` with this when argument is empty
if (e2e.components.Search.dashboardItems) {
e2e.components.Search.dashboardItems().each((item) => e2e().wrap(item).should('not.contain', title));
e2e.components.Search.dashboardItems().each((item) => cy.wrap(item).should('not.contain', title));
} else {
e2e()
.get('[aria-label^="Dashboard search item "]')
.each((item) => e2e().wrap(item).should('not.contain', title));
cy.get('[aria-label^="Dashboard search item "]').each((item) => cy.wrap(item).should('not.contain', title));
}
};

View File

@ -8,7 +8,7 @@ export interface DeleteDataSourceConfig {
}
export const deleteDataSource = ({ id, name, quick = false }: DeleteDataSourceConfig) => {
e2e().logToConsole('Deleting data source with name:', name);
cy.logToConsole('Deleting data source with name:', name);
if (quick) {
quickDelete(name);
@ -16,7 +16,7 @@ export const deleteDataSource = ({ id, name, quick = false }: DeleteDataSourceCo
uiDelete(name);
}
e2e().logToConsole('Deleted data source with name:', name);
cy.logToConsole('Deleted data source with name:', name);
e2e.getScenarioContext().then(({ addedDataSources }: any) => {
e2e.setScenarioContext({
@ -28,7 +28,7 @@ export const deleteDataSource = ({ id, name, quick = false }: DeleteDataSourceCo
};
const quickDelete = (name: string) => {
e2e().request('DELETE', fromBaseUrl(`/api/datasources/name/${name}`));
cy.request('DELETE', fromBaseUrl(`/api/datasources/name/${name}`));
};
const uiDelete = (name: string) => {
@ -40,7 +40,5 @@ const uiDelete = (name: string) => {
e2e.pages.DataSources.visit();
// @todo replace `e2e.pages.DataSources.dataSources` with this when argument is empty
e2e()
.get('[aria-label^="Data source list item "]')
.each((item) => e2e().wrap(item).should('not.contain', name));
cy.get('[aria-label^="Data source list item "]').each((item) => cy.wrap(item).should('not.contain', name));
};

View File

@ -17,7 +17,7 @@ export type Dashboard = { title: string; panels: Panel[]; uid: string; [key: str
* @param skipPanelValidation skip panel validation
*/
export const importDashboard = (dashboardToImport: Dashboard, queryTimeout?: number, skipPanelValidation?: boolean) => {
e2e().visit(fromBaseUrl('/dashboard/import'));
cy.visit(fromBaseUrl('/dashboard/import'));
// Note: normally we'd use 'click' and then 'type' here, but the json object is so big that using 'val' is much faster
e2e.components.DashboardImportPage.textarea().should('be.visible');
@ -28,11 +28,10 @@ export const importDashboard = (dashboardToImport: Dashboard, queryTimeout?: num
e2e.components.ImportDashboardForm.submit().should('be.visible').click();
// wait for dashboard to load
e2e().wait(queryTimeout || 6000);
cy.wait(queryTimeout || 6000);
// save the newly imported dashboard to context so it'll get properly deleted later
e2e()
.url()
cy.url()
.should('contain', '/d/')
.then((url: string) => {
const uid = getDashboardUid(url);

View File

@ -11,11 +11,9 @@ import { importDashboard, Dashboard } from './importDashboard';
* @param skipPanelValidation skips panel validation
*/
export const importDashboards = async (dirPath: string, queryTimeout?: number, skipPanelValidation?: boolean) => {
e2e()
.getJSONFilesFromDir(dirPath)
.then((jsonFiles: Dashboard[]) => {
jsonFiles.forEach((file) => {
importDashboard(file, queryTimeout || 6000, skipPanelValidation);
});
cy.getJSONFilesFromDir(dirPath).then((jsonFiles: Dashboard[]) => {
jsonFiles.forEach((file) => {
importDashboard(file, queryTimeout || 6000, skipPanelValidation);
});
});
};

View File

@ -16,7 +16,7 @@ const loginApi = (username: string, password: string) => {
};
const loginUi = (username: string, password: string) => {
e2e().logToConsole('Logging in with username:', username);
cy.logToConsole('Logging in with username:', username);
e2e.pages.Login.visit();
e2e.pages.Login.username()
.should('be.visible') // prevents flakiness
@ -29,7 +29,7 @@ const loginUi = (username: string, password: string) => {
e2e.pages.Login.skip().should('be.visible').click();
}
e2e().get('.login-page').should('not.exist');
cy.get('.login-page').should('not.exist');
};
export const login = (username = DEFAULT_USERNAME, password = DEFAULT_PASSWORD, loginViaApi = true) => {
@ -38,5 +38,5 @@ export const login = (username = DEFAULT_USERNAME, password = DEFAULT_PASSWORD,
} else {
loginUi(username, password);
}
e2e().logToConsole('Logged in with username:', username);
cy.logToConsole('Logged in with username:', username);
};

View File

@ -32,5 +32,5 @@ export const openDashboard = (config?: PartialOpenDashboardConfig) =>
}
// @todo remove `wrap` when possible
return e2e().wrap({ config: fullConfig }, { log: false });
return cy.wrap({ config: fullConfig }, { log: false });
});

View File

@ -19,12 +19,10 @@ export const selectOption = (config: SelectOptionConfig): any => {
container.within(() => {
if (clickToOpen) {
e2e()
.get('[class$="-input-suffix"]', { timeout: 1000 })
.then((element) => {
expect(Cypress.dom.isAttached(element)).to.eq(true);
e2e().get('[class$="-input-suffix"]', { timeout: 1000 }).click({ force: true });
});
cy.get('[class$="-input-suffix"]', { timeout: 1000 }).then((element) => {
expect(Cypress.dom.isAttached(element)).to.eq(true);
cy.get('[class$="-input-suffix"]', { timeout: 1000 }).click({ force: true });
});
}
});

View File

@ -12,8 +12,8 @@ export const setTimeRange = ({ from, to, zone }: TimeRangeConfig) => {
e2e.components.TimePicker.openButton().click();
if (zone) {
e2e().contains('button', 'Change time settings').click();
e2e().log('setting time zone to ' + zone);
cy.contains('button', 'Change time settings').click();
cy.log('setting time zone to ' + zone);
if (e2e.components.TimeZonePicker.containerV2) {
selectOption({

View File

@ -7,7 +7,7 @@ import { e2eScenario, ScenarioArguments } from './support/scenario';
import { getScenarioContext, setScenarioContext } from './support/scenarioContext';
import * as typings from './typings';
const e2eObject = {
export const e2e = {
env: (args: string) => Cypress.env(args),
config: () => Cypress.config(),
blobToBase64String: (blob: Blob) => Cypress.Blob.blobToBase64String(blob),
@ -22,5 +22,3 @@ const e2eObject = {
setScenarioContext,
getSelectors: <T extends Selectors>(selectors: E2ESelectors<T>) => e2eFactory({ selectors }),
};
export const e2e: (() => Cypress.cy) & typeof e2eObject = Object.assign(() => cy, e2eObject);

View File

@ -49,28 +49,24 @@ export const benchmark = ({
return it(testName, () => {
e2e.flows.openDashboard();
e2e().wait(dashboard.delayAfterOpening);
cy.wait(dashboard.delayAfterOpening);
if (appStats) {
const startCollecting = appStats.startCollecting;
if (startCollecting) {
e2e()
.window()
.then((win) => startCollecting(win));
cy.window().then((win) => startCollecting(win));
}
e2e().startBenchmarking(testName);
e2e().wait(duration);
cy.startBenchmarking(testName);
cy.wait(duration);
e2e()
.window()
.then((win) => {
e2e().stopBenchmarking(testName, appStats.collect(win));
});
cy.window().then((win) => {
cy.stopBenchmarking(testName, appStats.collect(win));
});
} else {
e2e().startBenchmarking(testName);
e2e().wait(duration);
e2e().stopBenchmarking(testName, {});
cy.startBenchmarking(testName);
cy.wait(duration);
cy.stopBenchmarking(testName, {});
}
});
});

View File

@ -2,9 +2,7 @@ import { e2e } from '../index';
// @todo this actually returns type `Cypress.Chainable`
const get = (key: string): any =>
e2e()
.wrap({ getLocalStorage: () => localStorage.getItem(key) }, { log: false })
.invoke('getLocalStorage');
cy.wrap({ getLocalStorage: () => localStorage.getItem(key) }, { log: false }).invoke('getLocalStorage');
// @todo this actually returns type `Cypress.Chainable`
export const getLocalStorage = (key: string): any =>

View File

@ -37,7 +37,7 @@ const lastProperty = <T extends DeleteDashboardConfig | DeleteDataSourceConfig,
) => items[items.length - 1]?.[key] ?? '';
export const getScenarioContext = (): Cypress.Chainable<ScenarioContext> =>
e2e()
cy
.wrap(
{
getScenarioContext: (): ScenarioContext => ({ ...scenarioContext }),
@ -47,7 +47,7 @@ export const getScenarioContext = (): Cypress.Chainable<ScenarioContext> =>
.invoke({ log: false }, 'getScenarioContext');
export const setScenarioContext = (newContext: Partial<ScenarioContext>): Cypress.Chainable<ScenarioContext> =>
e2e()
cy
.wrap(
{
setScenarioContext: () => {

View File

@ -1,7 +1,5 @@
import { CssSelector, FunctionSelector, Selectors, StringSelector, UrlSelector } from '@grafana/e2e-selectors';
import { e2e } from '../index';
import { Selector } from './selector';
import { fromBaseUrl } from './url';
@ -34,7 +32,7 @@ export type E2EFactoryArgs<S extends Selectors> = { selectors: S };
export type CypressOptions = Partial<Cypress.Loggable & Cypress.Timeoutable & Cypress.Withinable & Cypress.Shadow>;
const processSelectors = <S extends Selectors>(e2eObjects: E2EFunctions<S>, selectors: S): E2EFunctions<S> => {
const logOutput = (data: any) => e2e().logToConsole('Retrieving Selector:', data);
const logOutput = (data: any) => cy.logToConsole('Retrieving Selector:', data);
const keys = Object.keys(selectors);
for (let index = 0; index < keys.length; index++) {
const key = keys[index];
@ -52,11 +50,11 @@ const processSelectors = <S extends Selectors>(e2eObjects: E2EFunctions<S>, sele
parsedUrl = fromBaseUrl(value(args));
}
e2e().logToConsole('Visiting', parsedUrl);
cy.logToConsole('Visiting', parsedUrl);
if (queryParams) {
return e2e().visit({ url: parsedUrl, qs: queryParams });
return cy.visit({ url: parsedUrl, qs: queryParams });
} else {
return e2e().visit(parsedUrl);
return cy.visit(parsedUrl);
}
};
@ -71,7 +69,7 @@ const processSelectors = <S extends Selectors>(e2eObjects: E2EFunctions<S>, sele
? Selector.fromDataTestId(value)
: Selector.fromAriaLabel(value);
return e2e().get(selector, options);
return cy.get(selector, options);
};
continue;
@ -85,7 +83,7 @@ const processSelectors = <S extends Selectors>(e2eObjects: E2EFunctions<S>, sele
const selector = value(undefined as unknown as string);
logOutput(selector);
return e2e().get(selector);
return cy.get(selector);
}
// the input can be (text) or (options)
@ -97,12 +95,12 @@ const processSelectors = <S extends Selectors>(e2eObjects: E2EFunctions<S>, sele
: Selector.fromAriaLabel(selectorText);
logOutput(selector);
return e2e().get(selector);
return cy.get(selector);
}
const selector = value(undefined as unknown as string);
logOutput(selector);
return e2e().get(selector, textOrOptions);
return cy.get(selector, textOrOptions);
}
// the input can only be (text, options)
@ -114,7 +112,7 @@ const processSelectors = <S extends Selectors>(e2eObjects: E2EFunctions<S>, sele
: Selector.fromAriaLabel(selectorText);
logOutput(selector);
return e2e().get(selector, options);
return cy.get(selector, options);
}
};

View File

@ -12,8 +12,7 @@ e2e.scenario({
// open Panel Tests - Bar Gauge
e2e.flows.openDashboard({ uid: 'O6f11TZWk' });
e2e()
.get(`[data-panelid=6] [data-testid^="${selectors.components.Panels.Visualization.BarGauge.valueV2}"]`)
cy.get(`[data-panelid=6] [data-testid^="${selectors.components.Panels.Visualization.BarGauge.valueV2}"]`)
.should('have.css', 'color', 'rgb(242, 73, 92)')
.contains('100');
},

View File

@ -12,7 +12,7 @@ const addDataSource = () => {
e2e.components.DataSource.DataSourceHttpSettings.urlInput().type('http://prom-url:9090');
e2e.components.DataSourcePicker.inputV2().click({ force: true }).should('have.focus');
e2e().contains('gdev-tempo').scrollIntoView().should('be.visible').click();
cy.contains('gdev-tempo').scrollIntoView().should('be.visible').click();
},
});
};
@ -21,18 +21,18 @@ describe('Exemplars', () => {
beforeEach(() => {
e2e.flows.login('admin', 'admin');
e2e()
.request({ url: `${e2e.env('BASE_URL')}/api/datasources/name/${dataSourceName}`, failOnStatusCode: false })
.then((response) => {
cy.request({ url: `${e2e.env('BASE_URL')}/api/datasources/name/${dataSourceName}`, failOnStatusCode: false }).then(
(response) => {
if (response.isOkStatusCode) {
return;
}
addDataSource();
});
}
);
});
it('should be able to navigate to configured data source', () => {
e2e().intercept(
cy.intercept(
{
pathname: '/api/ds/query',
},
@ -51,7 +51,7 @@ describe('Exemplars', () => {
e2e.pages.Explore.visit();
e2e.components.DataSourcePicker.container().should('be.visible').click();
e2e().contains(dataSourceName).scrollIntoView().should('be.visible').click();
cy.contains(dataSourceName).scrollIntoView().should('be.visible').click();
// Switch to code editor
cy.contains('label', 'Code').click();
@ -78,7 +78,7 @@ describe('Exemplars', () => {
});
e2e.components.DataSource.Prometheus.exemplarMarker().first().trigger('mouseover');
e2e().contains('Query with gdev-tempo').click();
cy.contains('Query with gdev-tempo').click();
e2e.components.TraceViewer.spanBar().should('have.length', 11);
});
});

View File

@ -23,12 +23,12 @@ e2e.scenario({
.scrollIntoView()
.should('be.visible')
.within(() => {
e2e().get('input[id*="test-data-scenario-select-"]').should('be.visible').click();
cy.get('input[id*="test-data-scenario-select-"]').should('be.visible').click();
});
cy.contains('CSV Metric Values').scrollIntoView().should('be.visible').click();
const canvases = e2e().get('canvas');
const canvases = cy.get('canvas');
canvases.should('have.length', 1);
// Both queries above should have been run and be shown in the query history

View File

@ -50,7 +50,7 @@ e2e.scenario({
e2e.pages.Dashboard.SubMenu.Annotations.annotationToggle('Red, only panel 1').should('be.checked');
});
e2e().wait(3000);
cy.wait(3000);
e2e.components.Panels.Panel.title('Panel one')
.should('exist')

View File

@ -13,7 +13,7 @@ e2e.scenario({
cy.wait(1000);
// check that gauges are rendered
e2e().get('body').find(`.flot-base`).should('have.length', 16);
cy.get('body').find(`.flot-base`).should('have.length', 16);
// check that no panel errors exist
e2e.components.Panels.Panel.headerCornerInfo('error').should('not.exist');

View File

@ -10,12 +10,12 @@ e2e.scenario({
skipScenario: false,
scenario: () => {
e2e.flows.openDashboard({ uid: DASHBOARD_ID });
e2e().contains(DASHBOARD_NAME).should('be.visible');
cy.contains(DASHBOARD_NAME).should('be.visible');
cy.contains('uplot-main-div').should('not.exist');
e2e.flows.openDashboard({ uid: DASHBOARD_ID, queryParams: { '__feature.autoMigrateOldPanels': true } });
e2e().wait(1000);
cy.wait(1000);
e2e.components.Panels.Panel.title('Business Hours')
.should('exist')

View File

@ -10,7 +10,7 @@ e2e.scenario({
skipScenario: false,
scenario: () => {
// @ts-ignore some typing issue
e2e().on('uncaught:exception', (err) => {
cy.on('uncaught:exception', (err) => {
if (err.stack?.indexOf("TypeError: Cannot read property 'getText' of null") !== -1) {
// On occasion monaco editor will not have the time to be properly unloaded when we change the tab
// and then the e2e test fails with the uncaught:exception:

View File

@ -7,7 +7,7 @@ const addDataSource = () => {
expectedAlertMessage: 'Unable to connect with Loki. Please check the server logs for more details.',
name: dataSourceName,
form: () => {
e2e().get('#connection-url').type('http://loki-url:3100');
cy.get('#connection-url').type('http://loki-url:3100');
},
});
};
@ -21,20 +21,20 @@ e2e.scenario({
scenario: () => {
addDataSource();
e2e().intercept(/labels?/, (req) => {
cy.intercept(/labels?/, (req) => {
req.reply({ status: 'success', data: ['instance', 'job', 'source'] });
});
e2e().intercept(/series?/, (req) => {
cy.intercept(/series?/, (req) => {
req.reply({ status: 'success', data: [{ instance: 'instance1' }] });
});
// Go to Explore and choose Loki data source
e2e.pages.Explore.visit();
e2e.components.DataSourcePicker.container().should('be.visible').click();
e2e().contains(dataSourceName).scrollIntoView().should('be.visible').click();
cy.contains(dataSourceName).scrollIntoView().should('be.visible').click();
e2e().contains('Code').click();
cy.contains('Code').click();
// Wait for lazy loading
const monacoLoadingText = 'Loading...';
@ -44,55 +44,45 @@ e2e.scenario({
// adds closing braces around empty value
e2e.components.QueryField.container().type('time(');
e2e()
.get('.monaco-editor textarea:first')
.should(($el) => {
expect($el.val()).to.eq('time()');
});
cy.get('.monaco-editor textarea:first').should(($el) => {
expect($el.val()).to.eq('time()');
});
// removes closing brace when opening brace is removed
e2e.components.QueryField.container().type('{selectall}{backspace}avg_over_time({backspace}');
e2e()
.get('.monaco-editor textarea:first')
.should(($el) => {
expect($el.val()).to.eq('avg_over_time');
});
cy.get('.monaco-editor textarea:first').should(($el) => {
expect($el.val()).to.eq('avg_over_time');
});
// keeps closing brace when opening brace is removed and inner values exist
e2e.components.QueryField.container().type(
'{selectall}{backspace}time(test{leftArrow}{leftArrow}{leftArrow}{leftArrow}{backspace}'
);
e2e()
.get('.monaco-editor textarea:first')
.should(($el) => {
expect($el.val()).to.eq('timetest)');
});
cy.get('.monaco-editor textarea:first').should(($el) => {
expect($el.val()).to.eq('timetest)');
});
// overrides an automatically inserted brace
e2e.components.QueryField.container().type('{selectall}{backspace}time()');
e2e()
.get('.monaco-editor textarea:first')
.should(($el) => {
expect($el.val()).to.eq('time()');
});
cy.get('.monaco-editor textarea:first').should(($el) => {
expect($el.val()).to.eq('time()');
});
// does not override manually inserted braces
e2e.components.QueryField.container().type('{selectall}{backspace}))');
e2e()
.get('.monaco-editor textarea:first')
.should(($el) => {
expect($el.val()).to.eq('))');
});
cy.get('.monaco-editor textarea:first').should(($el) => {
expect($el.val()).to.eq('))');
});
/** Runner plugin */
// Should execute the query when enter with shift is pressed
e2e.components.QueryField.container().type('{selectall}{backspace}{shift+enter}');
e2e().get('[data-testid="explore-no-data"]').should('be.visible');
cy.get('[data-testid="explore-no-data"]').should('be.visible');
/** Suggestions plugin */
e2e.components.QueryField.container().type('{selectall}av');
e2e().contains('avg').should('be.visible');
e2e().contains('avg_over_time').should('be.visible');
cy.contains('avg').should('be.visible');
cy.contains('avg_over_time').should('be.visible');
},
});

View File

@ -8,7 +8,7 @@ const addDataSource = () => {
expectedAlertMessage: 'Unable to connect with Loki. Please check the server logs for more details.',
name: dataSourceName,
form: () => {
e2e().get('#connection-url').type('http://loki-url:3100');
cy.get('#connection-url').type('http://loki-url:3100');
},
});
};
@ -19,80 +19,76 @@ describe('Loki query builder', () => {
beforeEach(() => {
e2e.flows.login('admin', 'admin');
e2e()
.request({ url: `${e2e.env('BASE_URL')}/api/datasources/name/${dataSourceName}`, failOnStatusCode: false })
.then((response) => {
cy.request({ url: `${e2e.env('BASE_URL')}/api/datasources/name/${dataSourceName}`, failOnStatusCode: false }).then(
(response) => {
if (response.isOkStatusCode) {
return;
}
addDataSource();
});
}
);
});
it('should be able to use all modes', () => {
e2e()
.intercept(/labels\?/, (req) => {
req.reply({ status: 'success', data: ['instance', 'job', 'source'] });
})
.as('labelsRequest');
cy.intercept(/labels\?/, (req) => {
req.reply({ status: 'success', data: ['instance', 'job', 'source'] });
}).as('labelsRequest');
e2e().intercept(/series?/, (req) => {
cy.intercept(/series?/, (req) => {
req.reply({ status: 'success', data: [{ instance: 'instance1' }] });
});
e2e()
.intercept(/values/, (req) => {
req.reply({ status: 'success', data: ['instance1', 'instance2'] });
})
.as('valuesRequest');
cy.intercept(/values/, (req) => {
req.reply({ status: 'success', data: ['instance1', 'instance2'] });
}).as('valuesRequest');
// Go to Explore and choose Loki data source
e2e.pages.Explore.visit();
e2e.components.DataSourcePicker.container().should('be.visible').click();
e2e().contains(dataSourceName).scrollIntoView().should('be.visible').click();
cy.contains(dataSourceName).scrollIntoView().should('be.visible').click();
// Start in builder mode, click and choose query pattern
e2e.components.QueryBuilder.queryPatterns().click();
e2e().contains('Log query starters').click();
e2e().contains('Use this query').click();
e2e().contains('No pipeline errors').should('be.visible');
e2e().contains('Logfmt').should('be.visible');
e2e().contains('{} | logfmt | __error__=``').should('be.visible');
cy.contains('Log query starters').click();
cy.contains('Use this query').click();
cy.contains('No pipeline errors').should('be.visible');
cy.contains('Logfmt').should('be.visible');
cy.contains('{} | logfmt | __error__=``').should('be.visible');
// Add operation
e2e().contains('Operations').should('be.visible').click();
e2e().contains('Range functions').should('be.visible').click();
e2e().contains('Rate').should('be.visible').click();
e2e().contains('rate({} | logfmt | __error__=`` [$__auto]').should('be.visible');
cy.contains('Operations').should('be.visible').click();
cy.contains('Range functions').should('be.visible').click();
cy.contains('Rate').should('be.visible').click();
cy.contains('rate({} | logfmt | __error__=`` [$__auto]').should('be.visible');
// Check for expected error
e2e().contains(MISSING_LABEL_FILTER_ERROR_MESSAGE).should('be.visible');
cy.contains(MISSING_LABEL_FILTER_ERROR_MESSAGE).should('be.visible');
// Add labels to remove error
e2e.components.QueryBuilder.labelSelect().should('be.visible').click();
// wait until labels are loaded and set on the component before starting to type
e2e().wait('@labelsRequest');
e2e().wait(100);
cy.wait('@labelsRequest');
cy.wait(100);
e2e.components.QueryBuilder.labelSelect().type('instance{enter}');
e2e.components.QueryBuilder.matchOperatorSelect().should('be.visible').click().type('=~{enter}');
e2e.components.QueryBuilder.valueSelect().should('be.visible').click();
e2e().wait('@valuesRequest');
e2e().wait(100);
cy.wait('@valuesRequest');
cy.wait(100);
e2e.components.QueryBuilder.valueSelect().type('instance1{enter}').type('instance2{enter}');
e2e().contains(MISSING_LABEL_FILTER_ERROR_MESSAGE).should('not.exist');
e2e().contains(finalQuery).should('be.visible');
cy.contains(MISSING_LABEL_FILTER_ERROR_MESSAGE).should('not.exist');
cy.contains(finalQuery).should('be.visible');
// Change to code editor
e2e().contains('label', 'Code').click();
// We need to test this manually because the final query is split into separate DOM elements using e2e().contains(finalQuery).should('be.visible'); does not detect the query.
e2e().contains('rate').should('be.visible');
e2e().contains('instance1|instance2').should('be.visible');
e2e().contains('logfmt').should('be.visible');
e2e().contains('__error__').should('be.visible');
e2e().contains('$__auto').should('be.visible');
cy.contains('label', 'Code').click();
// We need to test this manually because the final query is split into separate DOM elements using cy.contains(finalQuery).should('be.visible'); does not detect the query.
cy.contains('rate').should('be.visible');
cy.contains('instance1|instance2').should('be.visible');
cy.contains('logfmt').should('be.visible');
cy.contains('__error__').should('be.visible');
cy.contains('$__auto').should('be.visible');
// Checks the explain mode toggle
e2e().contains('label', 'Explain').click();
e2e().contains('Fetch all log lines matching label filters.').should('be.visible');
cy.contains('label', 'Explain').click();
cy.contains('Fetch all log lines matching label filters.').should('be.visible');
});
});

View File

@ -12,8 +12,9 @@ e2e.scenario({
// open Panel Tests - Pie Chart
e2e.flows.openDashboard({ uid: 'lVE-2YFMz' });
e2e()
.get(`[data-panelid=11] [aria-label^="${selectors.components.Panels.Visualization.PieChart.svgSlice}"]`)
.should('have.length', 5);
cy.get(`[data-panelid=11] [aria-label^="${selectors.components.Panels.Visualization.PieChart.svgSlice}"]`).should(
'have.length',
5
);
},
});

View File

@ -13,7 +13,7 @@ e2e.scenario({
e2e.components.FolderPicker.containerV2()
.should('be.visible')
.within(() => {
e2e().get('#dashboard-folder-input').should('be.visible').click();
cy.get('#dashboard-folder-input').should('be.visible').click();
});
e2e.components.Select.option().should('be.visible').first().click();
@ -21,7 +21,7 @@ e2e.scenario({
e2e.components.FolderPicker.containerV2()
.should('be.visible')
.within(() => {
e2e().get('#dashboard-folder-input').should('exist').should('have.focus');
cy.get('#dashboard-folder-input').should('exist').should('have.focus');
});
e2e.pages.Dashboard.Settings.General.title().click();
@ -29,7 +29,7 @@ e2e.scenario({
e2e.components.FolderPicker.containerV2()
.should('be.visible')
.within(() => {
e2e().get('#dashboard-folder-input').should('exist').should('not.have.focus');
cy.get('#dashboard-folder-input').should('exist').should('not.have.focus');
});
},
});

View File

@ -10,6 +10,6 @@ e2e.scenario({
// open Panel Tests - Bar Gauge
e2e.pages.SoloPanel.visit('ZqZnVvFZz/datasource-tests-shared-queries?orgId=1&panelId=4');
e2e().get('canvas').should('have.length', 6);
cy.get('canvas').should('have.length', 6);
},
});

View File

@ -3,25 +3,26 @@ import { e2e } from '../utils';
describe('Trace view', () => {
it('Can lazy load big traces', () => {
e2e.flows.login('admin', 'admin');
e2e()
.intercept('GET', '**/api/traces/trace', {
fixture: 'long-trace-response.json',
})
.as('longTrace');
cy.intercept('GET', '**/api/traces/trace', {
fixture: 'long-trace-response.json',
}).as('longTrace');
e2e.pages.Explore.visit();
e2e.components.DataSourcePicker.container().should('be.visible').type('gdev-jaeger{enter}');
// Wait for the query editor to be set correctly
e2e.components.QueryEditorRows.rows().within(() => {
cy.contains('gdev-jaeger').should('be.visible');
});
e2e().wait(500);
// type this with 0 delay to prevent flaky tests due to cursor position changing between rerenders
e2e.components.QueryField.container().should('be.visible').type('trace', {
delay: 0,
});
// Use shift+enter to execute the query as it's more stable than clicking the execute button
e2e.components.QueryField.container().type('{shift+enter}');
e2e.components.QueryField.container().should('be.visible').type('trace', { delay: 100 });
e2e().wait(500);
e2e.components.RefreshPicker.runButtonV2().should('be.visible').click();
e2e().wait('@longTrace');
cy.wait('@longTrace');
e2e.components.TraceViewer.spanBar().should('be.visible');

View File

@ -11,14 +11,14 @@ e2e.scenario({
// Try visualization suggestions
e2e.components.PanelEditor.toggleVizPicker().click();
e2e().contains('Suggestions').click();
cy.contains('Suggestions').click();
cy.wait(3000);
// Verify we see suggestions
e2e.components.VisualizationPreview.card('Line chart').should('be.visible');
// Verify search works
e2e().get('[placeholder="Search for..."]').type('Table');
cy.get('[placeholder="Search for..."]').type('Table');
// Should no longer see line chart
e2e.components.VisualizationPreview.card('Line chart').should('not.exist');