From 4daf0acdb45644fd4225c8205c0d61652beba909 Mon Sep 17 00:00:00 2001 From: Aref Shafaei Date: Sat, 16 Sep 2023 15:05:17 -0700 Subject: [PATCH] add the rest of navbar test cases --- .github/workflows/e2e.yml | 18 +-- Makefile | 2 +- docs/dev-docs/e2e-test-writing.md | 12 +- docs/dev-docs/e2e-test.md | 4 + test/playwright/locators/modal.ts | 11 ++ test/playwright/locators/navbar.ts | 20 +-- test/playwright/locators/page.ts | 2 +- test/playwright/locators/recordset.ts | 16 +++ .../setup/playwright.configuration.ts | 13 +- test/playwright/setup/playwright.constant.ts | 12 -- .../playwright/setup/playwright.parameters.ts | 39 +++++ test/playwright/setup/playwright.pretest.ts | 2 + test/playwright/setup/playwright.setup.ts | 4 +- test/playwright/setup/playwright.teardown.ts | 4 +- .../navbar/no-logo.spec.ts | 23 +-- .../all-features/navbar/base-config.spec.ts | 134 +++++++++++++++--- .../navbar/catalog-chaise-config.config.ts | 7 + .../navbar/catalog-chaise-config.spec.ts | 60 ++++++++ .../delete-prohibited/playwright.config.ts | 7 + test/playwright/utils/user-utils.ts | 9 -- 20 files changed, 319 insertions(+), 80 deletions(-) create mode 100644 test/playwright/locators/modal.ts create mode 100644 test/playwright/locators/recordset.ts delete mode 100644 test/playwright/setup/playwright.constant.ts create mode 100644 test/playwright/setup/playwright.parameters.ts create mode 100644 test/playwright/specs/delete-prohibited/navbar/catalog-chaise-config.config.ts create mode 100644 test/playwright/specs/delete-prohibited/navbar/catalog-chaise-config.spec.ts create mode 100644 test/playwright/specs/delete-prohibited/playwright.config.ts diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index b823ffe5a..19c164775 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -152,12 +152,12 @@ jobs: run: | cd chaise make testallfeatures-playwright - # - name: Run delete prohibited test spec - # id: test-delete-prohibited - # continue-on-error: true - # run: | - # cd chaise - # make testdeleteprohibited-playwright + - name: Run delete prohibited test spec + id: test-delete-prohibited + continue-on-error: true + run: | + cd chaise + make testdeleteprohibited-playwright - name: Check on all features confirmation test spec if: always() && steps.test-all-features-confirmation.outcome != 'success' run: exit 1 @@ -167,9 +167,9 @@ jobs: - name: Check on all features test spec if: always() && steps.test-all-features.outcome != 'success' run: exit 1 - # - name: Check on delete prohibited test spec - # if: always() && steps.test-delete-prohibited.outcome != 'success' - # run: exit 1 + - name: Check on delete prohibited test spec + if: always() && steps.test-delete-prohibited.outcome != 'success' + run: exit 1 - uses: actions/upload-artifact@v3 if: always() with: diff --git a/Makefile b/Makefile index 4eff1a26e..f207dead4 100644 --- a/Makefile +++ b/Makefile @@ -186,7 +186,7 @@ testallfeaturesconfirmation-playwright: playwright-ALL_FEATURES_CONFIRMATION_PAR testdeleteprohibited: test-DELETE_PROHIBITED_PARALLEL_TESTS .PHONY: testdeleteprohibited-playwright -testdeleteprohibited-playwright: playwright-DELETE_PROHIBITED_PARALLEL_TESTS +testdeleteprohibited-playwright: playwright-DELETE_PROHIBITED_PARALLEL_TESTS_PLAYWRIGHT #Rule to run the default chaise configuration tests in parallel diff --git a/docs/dev-docs/e2e-test-writing.md b/docs/dev-docs/e2e-test-writing.md index 222a1d5f1..359c6b75a 100644 --- a/docs/dev-docs/e2e-test-writing.md +++ b/docs/dev-docs/e2e-test-writing.md @@ -16,7 +16,17 @@ In this document we try to summarize what are the best practices while writing t - (More applicable in ERMrestJS)Although it's preferable to not modify other schemas and create your very own schema that covers some specific test cases. - If you have multiple expect in your `it`, make sure they have their own error message. -- +- Use `expect.soft` if this is one of steps and we should be able to run the next steps even if it fails. + +- Common wait-fors: + +``` +profileModal.waitFor({ state: 'visible' }); + +profileModal.waitFor({ state: 'attached' }); + +profileModal.waitFor({ state: 'detached' }); +``` ## Test FAQ diff --git a/docs/dev-docs/e2e-test.md b/docs/dev-docs/e2e-test.md index e7e7406bd..321e3b7e5 100644 --- a/docs/dev-docs/e2e-test.md +++ b/docs/dev-docs/e2e-test.md @@ -174,6 +174,10 @@ TODO TODO +``` +page.pause(); +``` + ## Writing test Please use [this link](e2e-test-writing.md) to find more information about how to write new test cases. diff --git a/test/playwright/locators/modal.ts b/test/playwright/locators/modal.ts new file mode 100644 index 000000000..2ec522cfa --- /dev/null +++ b/test/playwright/locators/modal.ts @@ -0,0 +1,11 @@ +import { Locator, Page } from '@playwright/test'; + +export default class ModalLocators { + static getProfileModal(page: Page) : Locator { + return page.locator('.profile-popup'); + } + + static getCloseBtn (modal: Locator) : Locator { + return modal.locator('.modal-close'); + } +} diff --git a/test/playwright/locators/navbar.ts b/test/playwright/locators/navbar.ts index b4945e8e4..9295e3d5e 100644 --- a/test/playwright/locators/navbar.ts +++ b/test/playwright/locators/navbar.ts @@ -5,32 +5,32 @@ export default class NavbarLocators { return page.locator('#mainnav'); } - static getBanner(key: string, page: Page) : Locator { + static getBanner(key: string, page: Page): Locator { let selector = '.chaise-navbar-banner-container'; if (key) { - selector += '.chaise-navbar-banner-container-' + key; + selector += '.chaise-navbar-banner-container-' + key; } return page.locator(selector); } - static getBannerContent(key: string, page: Page) : Locator { + static getBannerContent(key: string, page: Page): Locator { const banner = NavbarLocators.getBanner(key, page); return banner.locator('.markdown-container'); } - static getBannerDismissBtn (key: string, page: Page) { - const banner = NavbarLocators.getBanner(key, page); + static getBannerDismissBtn(key: string, page: Page) { + const banner = NavbarLocators.getBanner(key, page); return banner.locator('.close'); -} - - static getTitle (page: any) { - return page.locator('#brand-text'); } - static getBrandImage(page: any) { + static getBrandImage(page: Page) { return page.locator('#brand-image') } + static getBrandText(page: Page) { + return page.locator('#brand-text') + } + static getUsername(page: Page) { return page.locator('.username-display'); } diff --git a/test/playwright/locators/page.ts b/test/playwright/locators/page.ts index 628102c18..5f3884488 100644 --- a/test/playwright/locators/page.ts +++ b/test/playwright/locators/page.ts @@ -1,4 +1,4 @@ -import { Locator, Page, BrowserContext } from '@playwright/test'; +import { Locator, BrowserContext } from '@playwright/test'; export default class PageLocators { diff --git a/test/playwright/locators/recordset.ts b/test/playwright/locators/recordset.ts new file mode 100644 index 000000000..d7d6d195a --- /dev/null +++ b/test/playwright/locators/recordset.ts @@ -0,0 +1,16 @@ +import { Locator, Page } from '@playwright/test'; + +export default class RecordsetLocators { + static async waitForRecordsetPageReady(page: Page) { + await RecordsetLocators.getRecordSetTable(page).waitFor({ state: 'visible' }); + } + + static async waitForAggregates(page: Page) { + page.locator('.table-column-spinner').waitFor({ state: 'hidden' }); + } + + static getRecordSetTable(page: Page): Locator { + return page.locator('.recordset-table'); + } + +} diff --git a/test/playwright/setup/playwright.configuration.ts b/test/playwright/setup/playwright.configuration.ts index 41ea5dfaf..530d3d83e 100644 --- a/test/playwright/setup/playwright.configuration.ts +++ b/test/playwright/setup/playwright.configuration.ts @@ -1,10 +1,9 @@ import { defineConfig, devices } from '@playwright/test'; import { resolve } from 'path'; -import { TestOptions } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.model'; import os from 'os'; - -export const STORAGE_STATE = resolve(__dirname, '../.auth/user.json'); +import { TestOptions } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.model'; +import { STORAGE_STATE } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.parameters'; const getConfig = (options: TestOptions) => { @@ -19,6 +18,8 @@ const getConfig = (options: TestOptions) => { throw new Error('ERMREST_URL and CHAISE_BASE_URL env variables are required.'); } + const reporterFolder = resolve(__dirname, `./../../../playwright-report/${options.testName}`); + const config = defineConfig({ testMatch: options.testMatch, @@ -40,15 +41,13 @@ const getConfig = (options: TestOptions) => { // Reporter to use reporter: process.env.CI ? [ - ['html', { open: 'never', outputFolder: resolve(__dirname, `./../../../playwright-report/${options.testName}`) }], + ['html', { open: 'never', outputFolder: reporterFolder }], ['github'] ] : [ - ['html', { open: 'never', outputFolder: resolve(__dirname, `./../../../playwright-report/${options.testName}`) }], + ['html', { open: 'never', outputFolder: reporterFolder }], ['list', { printSteps: true }] ], - // outputDir: resolve(__dirname, './../../../playwright-output'), - globalSetup: require.resolve('./playwright.setup'), globalTeardown: require.resolve('./playwright.teardown'), diff --git a/test/playwright/setup/playwright.constant.ts b/test/playwright/setup/playwright.constant.ts deleted file mode 100644 index 179d08ece..000000000 --- a/test/playwright/setup/playwright.constant.ts +++ /dev/null @@ -1,12 +0,0 @@ - -export const ERMREST_URL = process.env.ERMREST_URL; - -export const getCatalogID = () => process.env.CATALOG_ID; - - -// This is where we're writing the entities to. -// There are some system generated columns that we might want to know the value of, -// entities will have those. The problem is that we cannot just attach this variable -// to `global` since we might run test specs in multiple threads via sharding. -// Therefore we are writing these data this file, and then removing the file -export const ENTITIES_PATH = 'entities.json'; diff --git a/test/playwright/setup/playwright.parameters.ts b/test/playwright/setup/playwright.parameters.ts new file mode 100644 index 000000000..43c23360b --- /dev/null +++ b/test/playwright/setup/playwright.parameters.ts @@ -0,0 +1,39 @@ +import { resolve } from 'path'; + +export const ERMREST_URL = process.env.ERMREST_URL; + +/** + * return the catalog created for tests + * (populated during setup) + */ +export const getCatalogID = () : string => { + return process.env.CATALOG_ID!; +} + + +/** + * This is where we're writing the entities to. + * + * There are some system generated columns that we might want to know the value of, + * entities will have those. The problem is that we cannot just attach this variable + * to `global` since we might run test specs in multiple threads via sharding. + * Therefore we are writing these data this file, and then removing the file + * + * TODO is this limitation true with playwright? + */ +export const ENTITIES_PATH = 'entities.json'; + + +/** + * return the session object for the main user (catalog owner). + * (populated during setup) + */ +export const getMainUserSessionObject = () => { + return JSON.parse(process.env.WEBAUTHN_SESSION!); +} + + +/** + * the file that contains the logged in browser state + */ +export const STORAGE_STATE = resolve(__dirname, '../.auth/user.json'); diff --git a/test/playwright/setup/playwright.pretest.ts b/test/playwright/setup/playwright.pretest.ts index cc392f3ec..8903e52c3 100644 --- a/test/playwright/setup/playwright.pretest.ts +++ b/test/playwright/setup/playwright.pretest.ts @@ -1,4 +1,6 @@ import { test } from '@playwright/test'; + +// utils import { performLogin } from '@isrd-isi-edu/chaise/test/playwright/utils/user-utils'; test.describe('Login user', () => { diff --git a/test/playwright/setup/playwright.setup.ts b/test/playwright/setup/playwright.setup.ts index c462ffcaa..1c210b6d0 100644 --- a/test/playwright/setup/playwright.setup.ts +++ b/test/playwright/setup/playwright.setup.ts @@ -5,7 +5,7 @@ import fs from 'fs'; import { TestOptions } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.model'; import { removeCatalog, setupCatalog } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.import'; -import { ENTITIES_PATH } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.constant'; +import { ENTITIES_PATH, getCatalogID } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.parameters'; /** * @@ -279,7 +279,7 @@ function registerCallbacks(testConfiguration: any) { // If an uncaught exception is caught then simply call cleanup // to remove the created schema/catalog/tables if catalogId is not null process.on('uncaughtException', function (err) { - const catalogId = process.env.CATALOG_ID; + const catalogId = getCatalogID(); console.log(`in error : catalogId ${catalogId}`); console.dir(err); const cb = () => { diff --git a/test/playwright/setup/playwright.teardown.ts b/test/playwright/setup/playwright.teardown.ts index 4a0c56d85..f49f9842d 100644 --- a/test/playwright/setup/playwright.teardown.ts +++ b/test/playwright/setup/playwright.teardown.ts @@ -3,7 +3,7 @@ import fs from 'fs'; import { TestOptions } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.model'; import { removeCatalog } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.import'; -import { ENTITIES_PATH } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.constant'; +import { ENTITIES_PATH, getCatalogID } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.parameters'; async function globalTeardown(config: FullConfig) { /** @@ -31,7 +31,7 @@ async function globalTeardown(config: FullConfig) { // promises.push(pImport.deleteHatracNamespaces(testConfiguration.authCookie, testConfiguration.hatracNamespaces)); // } - const catalogId = process.env.CATALOG_ID; + const catalogId = getCatalogID(); if (testConfiguration.cleanup && testConfiguration.setup && catalogId != null) { await removeCatalog(catalogId); } diff --git a/test/playwright/specs/all-features-confirmation/navbar/no-logo.spec.ts b/test/playwright/specs/all-features-confirmation/navbar/no-logo.spec.ts index 256bb7e02..185fe0bfe 100644 --- a/test/playwright/specs/all-features-confirmation/navbar/no-logo.spec.ts +++ b/test/playwright/specs/all-features-confirmation/navbar/no-logo.spec.ts @@ -1,11 +1,14 @@ import { test, expect } from '@playwright/test'; + +// locators import NavbarLocators from '@isrd-isi-edu/chaise/test/playwright/locators/navbar'; import PageLocators from '@isrd-isi-edu/chaise/test/playwright/locators/page'; -import { getMainUserSessionObject } from '@isrd-isi-edu/chaise/test/playwright/utils/user-utils'; + +// utils +import { getMainUserSessionObject, getCatalogID } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.parameters'; test.describe('Navbar', () => { - const CATALOG_ID = process.env.CATALOG_ID; - const PAGE_URL = `/recordset/#${CATALOG_ID!}/product-navbar:accommodation`; + const PAGE_URL = `/recordset/#${getCatalogID()}/product-navbar:accommodation`; test.beforeEach(async ({ page, baseURL }) => { await page.goto(`${baseURL}${PAGE_URL}`); @@ -20,7 +23,7 @@ test.describe('Navbar', () => { await test.step('should display the right title from chaiseConfig.', async () => { // default heuristics - await expect.soft(NavbarLocators.getTitle(page)).toHaveText('Chaise'); + await expect.soft(NavbarLocators.getBrandText(page)).toHaveText('Chaise'); }); await test.step('should include the headTitle from chaiseConfig in the tab title (head > title)', async () => { @@ -94,7 +97,7 @@ test.describe('Navbar', () => { const newPage = await PageLocators.clickNewTabLink(searchOption, context); await newPage.waitForURL('**/chaise/search/#1/isa:dataset**'); - newPage.close(); + await newPage.close(); }); } @@ -112,9 +115,8 @@ test.describe('Navbar', () => { // check that clicking opens the link const newPage = await PageLocators.clickNewTabLink(datasetOption, context); - page.pause(); - await newPage.waitForURL(`**/chaise/recordset/#${CATALOG_ID}/isa:dataset**`); - newPage.close(); + await newPage.waitForURL(`**/chaise/recordset/#${getCatalogID()}/isa:dataset**`); + await newPage.close(); }); }); @@ -124,8 +126,9 @@ test.describe('Navbar', () => { const loginMenu = NavbarLocators.getLoginMenu(page); await test.step('should show the "Display Name" of the logged in user in the top right based on chaise-config property', async () => { - const name = getMainUserSessionObject().client.display_name; - await expect.soft(NavbarLocators.getUsername(page)).toHaveText(name); + const session = getMainUserSessionObject(); + expect.soft(session.client).toBeTruthy(); + await expect.soft(username).toHaveText(session.client.display_name); }); await test.step('clicking on username should open the login dropdown menu.', async () => { diff --git a/test/playwright/specs/all-features/navbar/base-config.spec.ts b/test/playwright/specs/all-features/navbar/base-config.spec.ts index 1b42fe8b9..2d8614fcb 100644 --- a/test/playwright/specs/all-features/navbar/base-config.spec.ts +++ b/test/playwright/specs/all-features/navbar/base-config.spec.ts @@ -1,36 +1,138 @@ import { test, expect } from '@playwright/test'; + +// locators import NavbarLocators from '@isrd-isi-edu/chaise/test/playwright/locators/navbar'; -import { getMainUserSessionObject } from '@isrd-isi-edu/chaise/test/playwright/utils/user-utils'; +import ModalLocators from '@isrd-isi-edu/chaise/test/playwright/locators/modal'; + +// utils +import { getMainUserSessionObject, getCatalogID } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.parameters'; test.describe('Navbar', () => { + const PAGE_URL = `/recordset/#${getCatalogID()}/product-navbar:accommodation`; - test('basic features,', async ({ page, baseURL }) => { - const navbar = page.locator('#mainnav'); + test.beforeEach(async ({ page, baseURL }) => { + await page.goto(`${baseURL}${PAGE_URL}`); + }) - await test.step('navbar should be visible on load.', async () => { - await page.goto(`${baseURL}/recordset/#${process.env.CATALOG_ID!}/isa:dataset`); + test('basic features,', async ({ page }) => { + const navbar = NavbarLocators.getContainer(page); + await test.step('navbar should be visible on load.', async () => { await navbar.waitFor({ state: 'visible' }); - }) + }); - await test.step('navbar should have the proper brand text and logo', async () => { - await expect.soft(NavbarLocators.getBrandImage(page)).toHaveAttribute('src', '../images/genetic-data.png'); + await test.step('should display the right title from chaiseConfig', async () => { + await expect.soft(NavbarLocators.getBrandText(page)).toHaveText('test123') }); - await test.step('should show the "Full Name" of the logged in user in the top right', async () => { - const session = getMainUserSessionObject(); - if (session.client) { - const client = session.client; - const name = (!process.env.CI ? client.full_name : client.display_name); - await expect.soft(NavbarLocators.getUsername(page)).toHaveText(name); - } + await test.step('should use the brand image/logo specified in chaiseConfig', async () => { + await expect.soft(NavbarLocators.getBrandImage(page)).toHaveAttribute('src', '../images/genetic-data.png'); }); - await test.step('tab title should be correct', async () => { + await test.step('should include the headTitle from chaiseConfig in the tab title (head > title)', async () => { await page.waitForLoadState(); const title = await page.title(); + /** + * the expected value is misleading. we're only supposed to ignore this for the title which is tested above + * but should be used as part of the page/tab title + */ expect.soft(title).toContain('this one should be ignored in favor of navbarBrandText'); }); }); + + test('menu support', async ({ page }) => { + const menu = NavbarLocators.getMenu(page); + + await test.step('for the menu, should generate the correct # of list items based on acls to show/hide specific options', async () => { + /** + * Count the number of nodes that are being shown (top level and submenus) + * - Local: config has 14 but 1 is hidden by ACLs + * - CI: config has 14 but 7 are hidden based on ACLs + */ + await expect.soft(menu.locator('a')).toHaveCount(!process.env.CI ? 13 : 7); + }); + + await test.step('should prefer markdownName over name when both are defined', async () => { + await expect.soft(menu.locator('.chaise-nav-item').nth(1).locator('.dropdown-toggle')).toHaveText('Test Recordsets'); + }); + + await test.step('should render a markdown pattern using proper HTML', async () => { + // in ci we don't have the same globus groups so the "show" ACL hides the 3rd link ("Records") + const idx = (!process.env.CI ? 3 : 2); + + const html = await menu.locator('.chaise-nav-item').nth(idx).innerHTML(); + expect.soft(html).toContain('Recordedit'); + }); + + if (!process.env.CI) { + const editMenu = menu.locator('.chaise-nav-item').nth(3); + const disabledSubMenuOptions = editMenu.locator('a.disable-link'); + + await test.step('should have 4 top level dropdown menus', async () => { + await expect.soft(menu.locator('.chaise-nav-item')).toHaveCount(4); + }); + + await test.step('should have a disabled "Records" links', async () => { + const disabledEl = menu.locator('a.disable-link').nth(0); + await expect.soft(disabledEl, 'text missmatch').toHaveText('Records'); + }); + + await test.step('should have a header and a disabled "Edit Exisisting Record" submenu link (no children)', async () => { + await editMenu.click(); + await expect.soft(editMenu.locator('.chaise-dropdown-header').first(), 'submenu header text missmatch').toHaveText('For Mutating Data'); + + await expect.soft(disabledSubMenuOptions, 'wrong number of disabled options').toHaveCount(4); + await expect.soft(disabledSubMenuOptions.nth(0), 'first disabled link text missmatch').toHaveText('Edit Existing Record'); + }); + + await test.step('should have disabled "Edit Records" submenu link (has children)', async() => { + //menu should still be open from previous test case + await expect.soft(disabledSubMenuOptions.nth(1), 'second disabled link text missmatch').toHaveText('Edit Records'); + }); + + await test.step('should have a "mailto:" link displayed properly', async () => { + const links = editMenu.locator('.dropdown-menu a'); + await expect.soft(links, 'links length missmatch').toHaveCount(7); + + const el = links.nth(6); + await expect.soft(el, 'help link title missmatch').toHaveText('Help with Editing'); + await expect.soft(el, 'mailto link missmatch').toHaveAttribute('href', 'mailto:support@isrd.isi.edu.test'); + }); + } + }); + + test('login menu', async ({ page }) => { + const username = NavbarLocators.getUsername(page); + const loginMenu = NavbarLocators.getLoginMenu(page); + const profileLink = NavbarLocators.getProfileLink(page); + const profileModal = ModalLocators.getProfileModal(page); + + await test.step('should show the "Full Name" of the logged in user in the top right', async () => { + const session = getMainUserSessionObject(); + expect.soft(session.client).toBeTruthy(); + const name = !process.env.CI ? session.client.full_name : session.client.display_name; + await expect.soft(username).toHaveText(name); + }); + + await test.step('clicking on username should open the login dropdown menu.', async () => { + await username.click(); + await loginMenu.waitFor({ state: 'visible' }); + + await expect.soft(profileLink, 'profile link shows wrong text').toHaveText('My Profile'); + await expect.soft(NavbarLocators.getLogoutLink(page), 'logout link shows wrong text').toHaveText('Log Out'); + }); + + await test.step('should open the profile card on click of My Profile link', async () => { + await profileLink.click(); + + await profileModal.waitFor({ state: 'visible' }); + }); + + await test.step('should close the profile card on click of X on the modal window', async () => { + await ModalLocators.getCloseBtn(profileModal).click(); + + await profileModal.waitFor({ state: 'detached' }); + }); + }); }); diff --git a/test/playwright/specs/delete-prohibited/navbar/catalog-chaise-config.config.ts b/test/playwright/specs/delete-prohibited/navbar/catalog-chaise-config.config.ts new file mode 100644 index 000000000..887cacd25 --- /dev/null +++ b/test/playwright/specs/delete-prohibited/navbar/catalog-chaise-config.config.ts @@ -0,0 +1,7 @@ +import getConfig from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.configuration'; + +export default getConfig({ + testName: 'delete-prohibited/navbar', + configFileName: 'navbar/catalog-chaise-config.dev.json', + chaiseConfigFilePath: 'test/e2e/specs/delete-prohibited/chaise-config.js', +}); diff --git a/test/playwright/specs/delete-prohibited/navbar/catalog-chaise-config.spec.ts b/test/playwright/specs/delete-prohibited/navbar/catalog-chaise-config.spec.ts new file mode 100644 index 000000000..f07035dc7 --- /dev/null +++ b/test/playwright/specs/delete-prohibited/navbar/catalog-chaise-config.spec.ts @@ -0,0 +1,60 @@ +import { test, expect } from '@playwright/test'; + +// locators +import NavbarLocators from '@isrd-isi-edu/chaise/test/playwright/locators/navbar'; +import PageLocators from '@isrd-isi-edu/chaise/test/playwright/locators/page'; +import RecordsetLocators from '@isrd-isi-edu/chaise/test/playwright/locators/recordset'; + +// utils +import { getCatalogID } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.parameters'; + +test.describe('Navbar', () => { + const PAGE_URL = `/recordset/#${getCatalogID()}/catalog-config-navbar:config-table`; + + test('when navbar is visible', async ({ page, baseURL, context }) => { + const navbar = NavbarLocators.getContainer(page); + const loginMenuOption = navbar.locator('.login-menu-options'); + + await test.step('navbar should be visible on load.', async () => { + await page.goto(`${baseURL}${PAGE_URL}`); + await navbar.waitFor({ state: 'visible' }); + }); + + await test.step('should display the right title from catalog annotation chaiseConfig.', async () => { + await expect.soft(NavbarLocators.getBrandText(page)).toHaveText('override test123'); + }); + + await test.step('should not display a brand image/logo', async () => { + const brandImage = NavbarLocators.getBrandImage(page) + await expect.soft(brandImage).toBeVisible(); + await expect.soft(brandImage).toHaveAttribute('src', '../images/logo.png'); + }); + + await test.step('should show a banner on top of the navbar', async () => { + const banner = NavbarLocators.getBannerContent('', page); + await expect.soft(banner).toBeVisible(); + await expect.soft(banner).toHaveText('This is a banner with link'); + }); + + await test.step('should show a link for the login information since chaiseConfig.loggedInMenu is an object', async () => { + await expect.soft(loginMenuOption).toHaveText('Outbound Profile Link') + }); + + if (!process.env.CI) { + await test.step('should open a new tab when clicking the link for the login information', async () => { + const newPage = await PageLocators.clickNewTabLink(loginMenuOption, context); + + await newPage.close(); + }); + } + }); + + test('should hide the navbar bar if the hideNavbar query parameter is set to true', async ({ page, baseURL }) => { + await page.goto(`${baseURL}${PAGE_URL}?hideNavbar=true`); + + await RecordsetLocators.waitForRecordsetPageReady(page); + + await expect(NavbarLocators.getContainer(page)).not.toBeAttached(); + }); + +}); diff --git a/test/playwright/specs/delete-prohibited/playwright.config.ts b/test/playwright/specs/delete-prohibited/playwright.config.ts new file mode 100644 index 000000000..2df84a564 --- /dev/null +++ b/test/playwright/specs/delete-prohibited/playwright.config.ts @@ -0,0 +1,7 @@ +import getConfig from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.configuration'; + +export default getConfig({ + testName: 'delete-prohibited', + configFileName: 'parallel-configs/delete-prohibited.dev.json', + chaiseConfigFilePath: 'test/e2e/specs/delete-prohibited/chaise-config.js', +}); diff --git a/test/playwright/utils/user-utils.ts b/test/playwright/utils/user-utils.ts index cc60f1216..ba931692a 100644 --- a/test/playwright/utils/user-utils.ts +++ b/test/playwright/utils/user-utils.ts @@ -22,12 +22,3 @@ export const performLogin = (cookie: any) => { }); } - -/** - * return the session object for the main user (catalog owner). - */ -export const getMainUserSessionObject = () => { - const session = JSON.parse(process.env.WEBAUTHN_SESSION!); - expect.soft(session.client).toBeTruthy(); - return session; -}