From 8ca71c56510e46e3ecd067f959fbd26d87b67dc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=A3o=20s=C3=A1?= Date: Fri, 24 Mar 2023 16:22:57 +0000 Subject: [PATCH 1/2] fixed tests considering new UI --- .../osb-portal/test/e2e/main_flows.spec.ts | 231 ++++++++++++------ applications/osb-portal/test/e2e/selectors.ts | 23 +- 2 files changed, 170 insertions(+), 84 deletions(-) diff --git a/applications/osb-portal/test/e2e/main_flows.spec.ts b/applications/osb-portal/test/e2e/main_flows.spec.ts index 51757221..1609d680 100644 --- a/applications/osb-portal/test/e2e/main_flows.spec.ts +++ b/applications/osb-portal/test/e2e/main_flows.spec.ts @@ -15,30 +15,36 @@ const WORKSPACE_LOAD_TIMEOUT = TEN_MINUTES; const getCurrentWorkpaces: () => Promise> = async () => { const pageFrame = page.mainFrame(); - return await pageFrame.$$( - "#workspaces-list .workspace-content" - ) + return await pageFrame.$$("#workspaces-list .imageContainer"); }; const testApplication = (appName: string, appSelectors: Array, url: string) => async () => { console.log("Opening workspace with", appName); - await page.waitForSelector(selectors.OSB_LOGO); - await page.click(selectors.OSB_LOGO); - + + await page.goto( + process.env.APP_URL || "https://v2dev.opensourcebrain.org/" + ); + + if (appName == "NetPyNE") { + //due to the Close page popup that appears when you try and leave NetPyne + try { + await page.once("dialog", async function (dialog) { + await dialog.accept(); + // await dialog.dismiss(); + }); + } catch (error) {} + } await page.waitForSelector(selectors.SMOKE_TEST_WORKSPACE); // Try to open an already existing workspace await page.waitForSelector(selectors.FEATURE_WORKSPACES_TAB); await page.click(selectors.FEATURE_WORKSPACES_TAB); - await page.waitForSelector(selectors.WORKSPACES); const featuredWorkspaces = await getCurrentWorkpaces(); - - // Try to open an already existing workspace to speed up - + // Try to open your already existing workspace to speed up if (featuredWorkspaces.length > 0) { await page.click(".workspace-page-link"); } else { @@ -58,46 +64,107 @@ const testApplication = await page.waitForSelector(selectors.SELECT_APPLICATION); await page.click(selectors.SELECT_APPLICATION); - await page.mainFrame().$$eval("#split-button-menu li", (choices: Array, appName: string) => choices.forEach((choice: HTMLElement) => { - - if (choice?.innerText?.includes(appName)) { - console.log("Choosing app", appName) - choice.click(); - } - }, appName), appName); - + await page.mainFrame().$$eval( + "#split-button-menu li", + (choices: Array, appName: string) => + choices.forEach((choice: HTMLElement) => { + if (choice?.innerText?.includes(appName)) { + console.log("Choosing app", appName); + choice.click(); + } + }, appName), + appName + ); console.log("Loading", appName); await page.click(selectors.OPEN_WITH_APPLICATION); + + //There's a maximum number of servers per user + await page.on("response", async (response) => { + if ( + response.status() == "500" && + (page.url().endsWith("nwbexplorer") || + page.url().endsWith("netpyne") || + page.url().endsWith("jupyter")) + ) { + + try { + console.log("Max number of servers reached, restarting..."); + const elementHandle = await page.waitForSelector( + selectors.APPLICATION_FRAME + ); + const server_frame = await elementHandle.contentFrame(); + await server_frame.waitForSelector('a[href="/hub/home"]'); + await server_frame.click('a[href="/hub/home"]'); + await page.waitForTimeout(ONE_SECOND * 3); + + try { + await server_frame.waitForSelector(".stop-server"); + let stopServer; + while ( + (stopServer = await server_frame.waitForSelector(".stop-server")) + ) { + await stopServer.click(); + await page.waitForTimeout(ONE_SECOND); + } + } catch (error) {} + + try { + await server_frame.waitForSelector(".delete-server"); + let deleteServer; + while ( + (deleteServer = await server_frame.waitForSelector( + ".delete-server" + )) + ) { + await deleteServer.click(); + await page.waitForTimeout(ONE_SECOND); + } + } catch (error) {} + + try { + await server_frame.waitForSelector("#stop"); + await server_frame.click("#stop"); + await page.waitForTimeout(ONE_SECOND * 2); + } catch (error) {} + + try { + let startServer; + while ( + (startServer = await server_frame.waitForSelector("#start")) + ) { + await startServer.click(); + await page.waitForTimeout(ONE_SECOND); + } + } catch (error) {} + } catch (error) {} + } + }); + + await page.waitForTimeout(ONE_SECOND); + await page.waitForSelector(selectors.APPLICATION_FRAME, { timeout: ONE_SECOND, }); expect(page.url()).toContain(url); - const elementHandle = await page.waitForSelector( + const elementHandler = await page.waitForSelector( selectors.APPLICATION_FRAME, { timeout: ONE_SECOND, } ); - const frame = await elementHandle.contentFrame(); - - await frame.waitForSelector(selectors.SPAWN, { - timeout: ONE_MINUTE, - }); - - - - for(const appSelector of appSelectors) { - if(!frame.isDetached()) { + const frame = await elementHandler.contentFrame(); + for (const appSelector of appSelectors) { + if (!frame.isDetached()) { await frame.waitForSelector(appSelector, { timeout: WORKSPACE_LOAD_TIMEOUT, }); } } - console.log(appName, "loaded"); + await page.waitForTimeout(ONE_SECOND * 3); }; describe("OSB v2 Smoke Tests", () => { @@ -106,37 +173,30 @@ describe("OSB v2 Smoke Tests", () => { args: [ "--no-sandbox", `--window-size=1600,1000`, - "--ignore-certificate-errors" + "--ignore-certificate-errors", ], - headless: !process.env.PUPPETEER_DISPLAY, + headless: true, + devtools: false, defaultViewport: { width: 1600, height: 1000, }, }); + page = await browser.newPage(); console.log( "Checking page", process.env.APP_URL || "https://v2dev.opensourcebrain.org/" ); - - - }); - - beforeEach(async () => { - page = await browser.newPage(); - await page .goto(process.env.APP_URL || "https://v2dev.opensourcebrain.org/", { waitUntil: "networkidle0", }) .catch(() => {}); - await page.waitForSelector(selectors.WORKSPACES); - }); + console.log("Env", process.env); - afterEach(async () => { - await page.close(); + await page.waitForSelector(selectors.WORKSPACES); }); afterAll(() => { @@ -156,11 +216,8 @@ describe("OSB v2 Smoke Tests", () => { await page.waitForSelector(selectors.USERNAME); await page.waitForSelector(selectors.PASSWORD); expect(page.url()).toContain("accounts."); - await page.type( - selectors.USERNAME, - process.env.USERNAME || "simao_user_osb" - ); - await page.type(selectors.PASSWORD, process.env.PASSWORD || "metacell"); + await page.type(selectors.USERNAME, process.env.USERNAME || "simao-osb"); + await page.type(selectors.PASSWORD, process.env.PASSWORD || "test1"); await page.click(selectors.LOGIN_BUTTON); await page.waitForSelector(selectors.ALL_YOUR_WORKSPACES_TAB); @@ -170,22 +227,42 @@ describe("OSB v2 Smoke Tests", () => { test("Create workspace", async () => { console.log("Creating workspace"); + const privateWorkspacesBefore = await getCurrentWorkpaces(); + await page.click(selectors.CREATE_WORKSPACE); + await page.waitForSelector('ul[role = "menu"]'); + + await page.evaluate(() => { + let menuOptions = document.querySelectorAll( + 'li[role="menuitem"]' + ); + for (var i = 0; i < menuOptions.length; i++) { + menuOptions[i].innerText.includes("Workspace") && + menuOptions[i].click(); + } + }); + + await page.waitForTimeout(ONE_SECOND); + + await page.waitForSelector("#computational-modeling"); + await page.click("#data-analysis"); + await page.waitForSelector(selectors.WORKSPACE_CREATION_BOX); - const privateWorkspacesBefore = await getCurrentWorkpaces(); await page.type(selectors.WORKSPACE_NAME, "Smoke Test Workspace"); - await page.type(selectors.WORKSPACE_TAGS, "Test"); - await page.keyboard.press("Enter"); + await page.type( selectors.WORKSPACE_DESCRIPTION, "Workspace created by the Automated Smoke tests" ); await page.waitForSelector(selectors.CREATE_NEW_WORKSPACE, ONE_SECOND); await page.click(selectors.CREATE_NEW_WORKSPACE); + await page.waitForTimeout(ONE_SECOND * 3); await page.waitForSelector(selectors.SMOKE_TEST_WORKSPACE); await page.waitForSelector(selectors.YOUR_WORKSPACES); - await page.waitForSelector(".workspace-card"); - await page.waitForSelector(selectors.SMOKE_TEST_WORKSPACE); + const privateWorkspacesAfter = await getCurrentWorkpaces(); + expect(privateWorkspacesAfter.length).toBeGreaterThan( + privateWorkspacesBefore.length + ); }); test( @@ -193,42 +270,52 @@ describe("OSB v2 Smoke Tests", () => { testApplication("NWB Explorer", [selectors.NWB_APP], "/nwbexplorer") ); - test("Open workspace with Jupyter Lab", testApplication("JupyterLab", [ - selectors.JUPYTER_CONTENT], "/jupyter")); - - test("Open workspace with NetPyNE", testApplication("NetPyNE", [ - selectors.NETPYNE_CELL_BUTTON, - selectors.NETPYNE_MAIN_CONTAINER], "/netpyne")); - + test( + "Open workspace with NetPyNE", + testApplication( + "NetPyNE", + [selectors.NETPYNE_CELL_BUTTON, selectors.NETPYNE_MAIN_CONTAINER], + "/netpyne" + ) + ); + test( + "Open workspace with Jupyter Lab", + testApplication("JupyterLab", [selectors.JUPYTER_CONTENT], "/jupyter") + ); test("Delete created workspace", async () => { console.log("Deleting created workspace"); + await page.waitForSelector(selectors.OSB_LOGO); + await page.click(selectors.OSB_LOGO); + await page.waitForTimeout(ONE_SECOND); await page.waitForSelector(selectors.SMOKE_TEST_WORKSPACE); - - let menuBtn; - while(menuBtn = await page.mainFrame().$(selectors.WORKSPACE_OPTIONS_BTN)) { - + let menuBtn; + while ( + (menuBtn = await page.mainFrame().$(selectors.WORKSPACE_OPTIONS_BTN)) + ) { await menuBtn.click(); - await page.waitForSelector(".delete-workspace", {timeout: ONE_SECOND * 5}); - await page.evaluate(() => document.querySelector(".delete-workspace")?.click()); // page.click does not work on the popover - await page.waitForSelector(".delete-workspace", {hidden: true}); + await page.waitForTimeout(ONE_SECOND); + await page.waitForSelector(".delete-workspace", { timeout: ONE_SECOND }); + await page.click(".delete-workspace"); + await page.waitForSelector(".delete-workspace", { hidden: true }); await page.waitForTimeout(ONE_SECOND); } - - - - - }); + const WorkspacesAfterDelete = await getCurrentWorkpaces(); + expect(WorkspacesAfterDelete.length).toBe(0); + }); test("Logout", async () => { console.log("Logging out"); + + await page.waitForSelector(selectors.USER_MENU); await page.click(selectors.USER_MENU); await page.waitForSelector(selectors.LOGOUT_ACTION, { timeout: ONE_SECOND * 4, }); + await page.waitForSelector(selectors.WORKSPACES); }); }); diff --git a/applications/osb-portal/test/e2e/selectors.ts b/applications/osb-portal/test/e2e/selectors.ts index 5a071772..ce32ee26 100644 --- a/applications/osb-portal/test/e2e/selectors.ts +++ b/applications/osb-portal/test/e2e/selectors.ts @@ -1,27 +1,27 @@ //Selectors: -export const WORKSPACES = "#workspaces-list"; +export const WORKSPACES = "#workspaces-list"; export const PUBLIC_WORKSPACES = '#public-tab'; -export const SIGN_IN = 'button[class="MuiButtonBase-root MuiButton-root MuiButton-text jss9"]'; +export const SIGN_IN = 'button[class="MuiButtonBase-root MuiButton-root MuiButton-text jss9"]'; // export const USERNAME = "#username"; export const PASSWORD = "#password"; export const LOGIN_BTN = "button.sign-in" export const LOGOUT_ACTION = ".logout-menu-item" export const LOGIN_BUTTON = "#kc-login"; -export const ALL_YOUR_WORKSPACES_TAB = "#your-all-workspaces-tab"; +export const ALL_YOUR_WORKSPACES_TAB = "#your-all-workspaces-tab"; export const FEATURE_WORKSPACES_TAB = "#featured-tab"; -export const YOUR_WORKSPACES = 'div[class="MuiGrid-root MuiGrid-container MuiGrid-spacing-xs-1"]'; -export const CREATE_WORKSPACE = '#computational-modeling-item'; -export const CREATE_NEW_WORKSPACE = '#create-a-new-workspace-button' -export const WORKSPACE_CREATION_BOX = 'div[class="MuiDialogContent-root"]'; +export const YOUR_WORKSPACES = '.MuiGrid-spacing-xs-1'; +export const CREATE_WORKSPACE = '#create-new-workspace-repository'; +export const CREATE_NEW_WORKSPACE = '#create-a-new-workspace-button' +export const WORKSPACE_CREATION_BOX = '.MuiDialogContent-root'; export const WORKSPACE_NAME = "#workspaceName"; export const WORKSPACE_TAGS = 'input[class="MuiInputBase-input MuiFilledInput-input MuiAutocomplete-input MuiAutocomplete-inputFocused MuiInputBase-inputAdornedEnd MuiFilledInput-inputAdornedEnd"]'; export const WORKSPACE_DESCRIPTION = 'textarea[class="section-container input "]'; -export const OSB_LOGO = 'img[title="Open Source Brain"]'; -export const WORKSPACE_OPTIONS_BTN = '.btn-workspace-actions'; +export const OSB_LOGO = 'a[class="MuiTypography-root MuiTypography-inherit MuiLink-root MuiLink-underlineAlways css-u5zia9"]'; +export const WORKSPACE_OPTIONS_BTN = '.btn-actions'; export const WORKSPACE_OPTIONS_LIST = 'ul[class="MuiList-root MuiMenu-list MuiList-padding"]'; export const USER_MENU = '.user-menu-btn'; -export const SMOKE_TEST_WORKSPACE = 'a[title="Smoke Test Workspace"]'; -export const OPENED_WORKSPACE = '#panel1a-content'; +export const SMOKE_TEST_WORKSPACE = 'a[aria-label="Smoke Test Workspace"]'; +export const OPENED_WORKSPACE = '#workspace-detail-content'; export const SELECT_APPLICATION = '.split-button-control'; export const OPEN_WITH_APPLICATION = '.open-workspace'; export const NETPYNE_MAIN_CONTAINER = "#mainContainer"; @@ -29,4 +29,3 @@ export const NETPYNE_CELL_BUTTON = "#selectCellButton"; export const APPLICATION_FRAME = '#workspace-frame' export const NWB_APP = "#main-container-inner"; export const JUPYTER_CONTENT = '#jp-main-dock-panel'; -export const SPAWN = ".spawn-container" From ce8b4aac204fbf43f3e68752f55ea04ec9e0678f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sim=C3=A3o=20s=C3=A1?= Date: Fri, 24 Mar 2023 16:30:35 +0000 Subject: [PATCH 2/2] headless mode changed --- applications/osb-portal/test/e2e/main_flows.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/applications/osb-portal/test/e2e/main_flows.spec.ts b/applications/osb-portal/test/e2e/main_flows.spec.ts index 1609d680..95d8bf58 100644 --- a/applications/osb-portal/test/e2e/main_flows.spec.ts +++ b/applications/osb-portal/test/e2e/main_flows.spec.ts @@ -173,16 +173,16 @@ describe("OSB v2 Smoke Tests", () => { args: [ "--no-sandbox", `--window-size=1600,1000`, - "--ignore-certificate-errors", + "--ignore-certificate-errors" ], - headless: true, - devtools: false, + headless: !process.env.PUPPETEER_DISPLAY, defaultViewport: { width: 1600, height: 1000, }, }); + page = await browser.newPage(); console.log( "Checking page",