Skip to content

Commit

Permalink
test related table general features + share & cite popup + indv relat…
Browse files Browse the repository at this point in the history
…ed presentation
  • Loading branch information
RFSH committed Oct 27, 2023
1 parent f1f133f commit b6ef81b
Show file tree
Hide file tree
Showing 13 changed files with 513 additions and 63 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ common/styles/navbar.css
/playwright-report/
/playwright/.cache/
test/playwright/.auth
test/playwright/.download
3 changes: 2 additions & 1 deletion test/e2e/utils/record-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,11 +442,12 @@ exports.testPresentation = function (tableParams) {
/**
* opens the share and cite popup and test the content. The acceptable input:
* {
* title: "title", // required
* permalink: "the permalink", // required
* hasVersionedLink: boolean, // whether versioned link is present or not
* verifyVersionedLink: boolean, // if true, we will test the versioned link too.
* citation: string, // (optional) pass null if citation should not be displayed.
* bintextFile: string, // (optional) the location of the bibtext file so we can delete it after downloading it
* bibtextFile: string, // (optional) the location of the bibtext file so we can delete it after downloading it
* }
*/
exports.testSharePopup = function (sharePopupParams) {
Expand Down
69 changes: 67 additions & 2 deletions test/playwright/locators/modal.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,76 @@
import { Locator, Page } from '@playwright/test';

export default class ModalLocators {
static getProfileModal(page: Page) : Locator {

// ------------ modal container getters ------------ //

static getProfileModal(page: Page): Locator {
return page.locator('.profile-popup');
}

static getCloseBtn (modal: Locator) : Locator {
static getShareCiteModal(page: Page): Locator {
return page.locator('.chaise-share-citation-modal');
}

// ------------- common modal functions -------------- //

static getModalTitle(modal: Locator) {
return modal.locator('.modal-title');
}

static getModalText(modal: Locator) {
return modal.locator('.modal-body');
}

static getCloseBtn(modal: Locator): Locator {
return modal.locator('.modal-close');
}


// --------- share cite related functions ------------ //

static async waitForCitation(modal: Locator, timeout?: number): Promise<void> {
await modal.locator('.citation-loader').waitFor({ state: 'detached', timeout });
}

static getVersionedLinkElement(modal: Locator): Locator {
return modal.locator('.share-modal-versioned-link');
}

static getLiveLinkElement(modal: Locator): Locator {
return modal.locator('.share-modal-live-link');
}

static getModalListElements(modal: Locator): Locator {
return ModalLocators.getModalText(modal).locator('li');
}

static getShareLinkHeader(modal: Locator): Locator {
return modal.locator('.share-modal-links h2');
}

static getShareLinkSubHeaders(modal: Locator): Locator {
return modal.locator('.share-modal-links h3');
}

static getShareLinkCopyBtns(modal: Locator): Locator {
return modal.locator('.share-modal-links .chaise-copy-to-clipboard-btn')
}

static getCitationHeader(modal: Locator): Locator {
return modal.locator('.share-modal-citation h2');
}

static getDownloadCitationHeader(modal: Locator): Locator {
return modal.locator('.share-modal-download-citation h3');
}

static getCitationText(modal: Locator): Locator {
return modal.locator('.share-modal-citation-text');
}

static getBibtex(modal: Locator): Locator {
return modal.locator('.bibtex-download-btn');
}

}
20 changes: 12 additions & 8 deletions test/playwright/locators/navbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,40 @@ export default class NavbarLocators {
return banner.locator('.markdown-container');
}

static getBannerDismissBtn(key: string, page: Page) {
static getBannerDismissBtn(key: string, page: Page): Locator {
const banner = NavbarLocators.getBanner(key, page);
return banner.locator('.close');
}

static getBrandImage(page: Page) {
static getBrandImage(page: Page): Locator {
return page.locator('#brand-image')
}

static getBrandText(page: Page) {
static getBrandText(page: Page): Locator {
return page.locator('#brand-text')
}

static getUsername(page: Page) {
static getUsername(page: Page): Locator {
return page.locator('.username-display');
}

static getMenu(page: Page) {
static getMenu(page: Page): Locator {
return page.locator('.navbar-menu-options');
}

static getLoginMenu(page: Page) {
static getLoginMenuContainer(page: Page): Locator{
return NavbarLocators.getContainer(page).locator('.login-menu-options');
}

static getLoginMenu(page: Page): Locator {
return page.locator('.username-display > div.dropdown-menu');
}

static getProfileLink(page: Page) {
static getProfileLink(page: Page): Locator {
return page.locator('#profile-link');
}

static getLogoutLink(page: Page) {
static getLogoutLink(page: Page): Locator {
return page.locator('#logout-link');
}
}
34 changes: 33 additions & 1 deletion test/playwright/locators/page.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { Locator, BrowserContext } from '@playwright/test';
import { Page, Locator, BrowserContext, expect } from '@playwright/test';
import { DOWNLOAD_FOLDER } from '@isrd-isi-edu/chaise/test/playwright/setup/playwright.parameters';

export default class PageLocators {

/**
* click on the given link and return the opened page instance.
*
* Example:
* const newPage = await PageLocators.clickNewTabLink(someButton, context);
* await newPage.waitForURL('someURL');
* await newPage.close();
*/
static async clickNewTabLink(locator: Locator, context: BrowserContext) {
const pagePromise = context.waitForEvent('page');
Expand All @@ -12,4 +18,30 @@ export default class PageLocators {
await newPage.waitForLoadState();
return newPage;
}

/**
* click on the given element and verify that it initiated a download
* @param locator the button that will be clicked
* @param expectedFileName pass undefined if you don't want to test the actual file path and just test that something was downloaded.
* @param page the page object
*/
static async clickAndVerifyDownload(locator: Locator, expectedFileName: string | undefined, page: Page) {
const downloadPromise = page.waitForEvent('download');
await locator.click();
const download = await downloadPromise;
const filename = download.suggestedFilename();

// Wait for the download process to complete and save the downloaded file somewhere.
await download.saveAs(DOWNLOAD_FOLDER + '/' + filename);

if (expectedFileName) {
expect.soft(filename).toEqual(expectedFileName);
}

await download.delete();
}

static async getClipboardContent(page: Page) : Promise<string> {
return await page.evaluate('navigator.clipboard.readText()');
}
}
52 changes: 48 additions & 4 deletions test/playwright/locators/record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { makeSafeIdAttr } from '@isrd-isi-edu/chaise/src/utils/string-utils';
import { Locator, Page } from '@playwright/test';

export default class RecordLocators {
static async waitForRecordPageReady(page: Page) {
await RecordLocators.getEntityTitleElement(page).waitFor({ state: 'visible' });
await RecordLocators.getMainSectionTable(page).waitFor({ state: 'visible' });
await RecordLocators.getRelatedSectionSpinner(page).waitFor({ state: 'detached' })
static async waitForRecordPageReady(page: Page, timeout?: number) {
await RecordLocators.getEntityTitleElement(page).waitFor({ state: 'visible', timeout });
await RecordLocators.getMainSectionTable(page).waitFor({ state: 'visible', timeout });
await RecordLocators.getRelatedSectionSpinner(page).waitFor({ state: 'detached', timeout })
await RecordLocators.getTableOfContentsRelatedSpinner(page).waitFor({ state: 'detached', timeout })
}

static getEntityTitleElement(page: Page): Locator {
Expand All @@ -16,17 +17,60 @@ export default class RecordLocators {
return page.locator('.record-main-section-table');
}

static getEntityRelatedTable(page: Page, displayname: string): Locator {
displayname = makeSafeIdAttr(displayname);
return page.locator(`#entity-${displayname}`);
}

static getRelatedSectionSpinner(page: Page): Locator {
return page.locator('.related-section-spinner');
}

static getTableOfContentsRelatedSpinner(page: Page): Locator {
return page.locator('#rt-toc-loading');
}

static getDisplayedRelatedTableTitles(page: Page): Locator {
return page.locator('.chaise-accordion:not(.forced-hidden) .chaise-accordion-header .chaise-accordion-displayname')
}

static getRelatedTableAccordion(page: Page, displayname: string): Locator {
displayname = makeSafeIdAttr(displayname);
return page.locator(`#rt-heading-${displayname}`);
}

static getRelatedTableHeading(page: Page, displayname: string): Locator {
return RecordLocators.getRelatedTableAccordion(page, displayname).locator('.panel-heading');
}

static getRelatedTableSectionHeader(page: Page, displayname: string): Locator {
return RecordLocators.getRelatedTableHeading(page, displayname).locator('.chaise-accordion-header');
}

static getRelatedTableSectionHeaderDisplayname(page: Page, displayname: string): Locator {
return RecordLocators.getRelatedTableHeading(page, displayname).locator('.chaise-accordion-header .chaise-accordion-displayname');
}

static getRelatedTableInlineComment(page: Page, displayname: string): Locator {
return RecordLocators.getRelatedTableAccordion(page, displayname).locator('.inline-tooltip');
}

static getRelatedTableAccordionContent(page: Page, displayname: string): Locator {
const acc = RecordLocators.getRelatedTableAccordion(page, displayname);
return acc.locator('.accordion-collapse');
}

static getMoreResultsLink(page: Page, displayname: string, isInline?: boolean): Locator {
const loc = isInline ? RecordLocators.getEntityRelatedTable(page, displayname) : RecordLocators.getRelatedTableAccordion(page, displayname);
return loc.locator('.more-results-link');
}

static getSidePanelHeadings(page: Page): Locator {
return page.locator('.columns-container li.toc-heading');
}

static getShareButton(page: Page): Locator {
return page.locator('.share-cite-btn');
}

}
18 changes: 14 additions & 4 deletions test/playwright/locators/recordset.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
import { Locator, Page } from '@playwright/test';

export default class RecordsetLocators {
static async waitForRecordsetPageReady(page: Page) {
await RecordsetLocators.getRecordSetTable(page).waitFor({ state: 'visible' });
static async waitForRecordsetPageReady(page: Page, timeout?: number): Promise<void> {
await RecordsetLocators.getRecordSetTable(page).waitFor({ state: 'visible', timeout });

await page.locator('.recordest-main-spinner').waitFor({ state: 'detached', timeout });
}

static async waitForAggregates(page: Page, timeout?: number): Promise<void> {
await page.locator('.table-column-spinner').waitFor({ state: 'hidden', timeout });
}

static async waitForAggregates(page: Page) {
page.locator('.table-column-spinner').waitFor({ state: 'hidden' });
static getPageTitleElement(page: Page): Locator {
return page.locator('page-title');
}

static getRecordSetTable(page: Page): Locator {
return page.locator('.recordset-table');
}

static getFacetFilters(page: Page): Locator {
return page.locator('.chiclets-container .filter-chiclet');
}

}
35 changes: 20 additions & 15 deletions test/playwright/setup/playwright.configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ const getConfig = (options: TestOptions) => {

const reporterFolder = resolve(__dirname, `./../../../playwright-report/${options.testName}`);

const extraBrowserParams = {
storageState: STORAGE_STATE,
permissions: ['clipboard-read', 'clipboard-write']
};

const config = defineConfig({

testMatch: options.testMatch,
Expand All @@ -39,7 +44,10 @@ const getConfig = (options: TestOptions) => {
retries: 0,

// Opt out of parallel tests on CI.
// workers: process.env.CI ? 1 : undefined,
workers: process.env.CI ? 4 : undefined,

// the outputDir is used for screenshot or other tests that use a file, so we should define it anyways
outputDir: resolve(__dirname, `./../../../playwright-output/${options.testName}`),

// Reporter to use
reporter: process.env.CI ? [
Expand Down Expand Up @@ -70,21 +78,18 @@ const getConfig = (options: TestOptions) => {
{
name: 'chromium',
dependencies: ['pretest'],
use: {
...devices['Desktop Chrome'],
storageState: STORAGE_STATE
},
},
{
name: 'firefox',
dependencies: ['pretest'],
use: { ...devices['Desktop Firefox'], storageState: STORAGE_STATE },
},
{
name: 'webkit',
dependencies: ['pretest'],
use: { ...devices['Desktop Safari'], storageState: STORAGE_STATE },
use: { ...devices['Desktop Chrome'], ...extraBrowserParams },
},
// {
// name: 'firefox',
// dependencies: ['pretest'],
// use: { ...devices['Desktop Firefox'], ...extraBrowserParams },
// },
// {
// name: 'webkit',
// dependencies: ['pretest'],
// use: { ...devices['Desktop Safari'], ...extraBrowserParams },
// },
],
});

Expand Down
Loading

0 comments on commit b6ef81b

Please sign in to comment.