Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UIE-205] Puppeteer upgrade (version 22.7.1) #5117

Merged
merged 6 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,803 changes: 1,935 additions & 868 deletions .pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed .yarn/cache/ws-npm-8.5.0-8e99728c84-76f2f90e40.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion integration-tests/jest-circus-environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const PuppeteerEnvironment = require('jest-environment-puppeteer');
const { parse } = require('path');
const { maybeSaveScreenshot, savePageContent } = require('./utils/integration-utils');

class JestCircusEnvironment extends PuppeteerEnvironment {
class JestCircusEnvironment extends PuppeteerEnvironment.default {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puppeteer changed how this is exported.

constructor(config, context) {
super(config, context);
this.testName = parse(context.testPath).name;
Expand Down
42 changes: 2 additions & 40 deletions integration-tests/jest-puppeteer.config.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,11 @@
/* eslint-disable prefer-template */
const printWarning = (message) => {
if (process.env.warningPrinted) {
return;
}
console.warn('\n\x1b[1m' /* bold */ + '╔'.padEnd(80, '═') + '╗');
message.forEach((line) => {
console.warn(`║ ${line}`.padEnd(80) + '║');
});
console.warn('╚'.padEnd(80, '═') + '╝');
console.warn('\x1b[0m' /* not-bold */);
process.env.warningPrinted = true;
};

module.exports = {
browserContext: 'incognito',
launch: {
devtools: process.env.DEVTOOLS === 'true',
headless: process.env.HEADLESS !== 'false',
slowMo: process.env.SLOW === 'true' ? 250 : undefined,
defaultViewport: { width: 1200, height: 800 },
// Workaround for issue when accessing cross domain iframes in puppeteer while not headless:
// https://github.com/GoogleChrome/puppeteer/issues/4960
args: (({ headfull, devtools }) => {
const flag = '--disable-features=site-per-process';

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of this is needed anymore-- I ran the IA analysis test locally (which interacts with an iframe) with both HEADFUL and DEVTOOLS, and it passed.

if (headfull && devtools) {
printWarning([
'iframes Issue'.padStart(40),
'Dev tools cannot be opened in headless mode with the',
`${flag} flag set. If you are running tests`,
'with iframes they will fail with dev tools turned on.',
]);
return [];
}
if (headfull) {
printWarning([
'Chromium flag set'.padStart(40),
`Headfull mode also sets the ${flag} flag`,
'This allows iframe tests to work in Headfull mode.',
'If you notice unexpected side effects in your tests',
'you can disable this flag in src/jest-puppeteer.config.js',
]);
return [flag];
}
return [];
})({ headfull: process.env.HEADLESS === 'false', devtools: process.env.DEVTOOLS === 'true' }),
protocolTimeout: 720_000, // 12 minutes
args: [],
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point, Puppeteer decreased their default protocolTimeout. I needed to increase this for the IA analysis tests, which wait for a very long time for Jupyter or RStudio to launch and be ready to interact with.

},
};
10 changes: 5 additions & 5 deletions integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@
"test-flakes": "FLAKES=true yarn test-local --runInBand"
},
"devDependencies": {
"jest": "^27.4.3",
"jest-environment-puppeteer": "^6.0.3",
"jest": "^29.7.0",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I increased these all to their most recent version.

"jest-environment-puppeteer": "^10.1.1",
"jest-junit": "^13.0.0",
"jest-puppeteer": "^6.0.2",
"jest-puppeteer": "^10.1.1",
"node-fetch": "^2.6.7",
"prompts": "^2.4.1",
"puppeteer-cluster": "^0.23.0"
"puppeteer-cluster": "^0.24.0"
},
"dependencies": {
"@axe-core/puppeteer": "^4.6.0",
"date-fns": "^2.24.0",
"google-auth-library": "^7.9.2",
"lodash": "^4.17.21",
"p-retry": "^4.6.1",
"puppeteer": "^13.1.3",
"puppeteer": "22.7.1",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the last Puppeteer version that works with the IA iframes (using Chrome version 124.0.6367.78). All later versions I tried failed in the same way: broken computer icon in the iframe and a message about being unable to access dev leonardo.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdcanas just pinging you in case you might know, but it sounds like we eventually will need to rewrite our IA UI Integration tests to be better compatible with pupeteer?

"qs": "^6.10.1",
"uuid": "^8.3.2"
}
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/billing-projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const billingProjectsPage = (testPage, testUrl) => {

assertChartValue: async (number, workspaceName, category, cost) => {
// This checks the accessible text for chart values.
await testPage.waitForXPath(`(//*[@role="img"])[contains(@aria-label,"${number}. Workspace ${workspaceName}, ${category}: ${cost}.")]`);
await testPage.waitForSelector(`[role="img"][aria-label*="${number}. Workspace ${workspaceName}, ${category}: ${cost}."]`);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

waitForXPath has been removed.

},
};
};
Expand Down
4 changes: 2 additions & 2 deletions integration-tests/tests/find-workflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ const testFindWorkflowFn = _.flow(
without these lines it will redirect to dev-Terra even if started out at localhost:3000-Terra */
if (testUrl === 'http://localhost:3000') {
await findElement(page, clickable({ textContains: 'Yes' }));
const yesButtonHrefDetails = (await page.$x('//a[contains(text(), "Yes")]/@href'))[0];
const yesButtonHrefDetails = (await page.$$('xpath///a[contains(text(), "Yes")]/@href'))[0];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename of this method, and you have to specify 'xpath/' at the beginning if using an xpath.

const href = await page.evaluate((yesButton) => yesButton.textContent, yesButtonHrefDetails);
const redirectURL = _.replace(/https:\/\/bvdp-saturn-(dev|staging).appspot.com/, testUrl, href);
await gotoPage(page, redirectURL);
} else {
await click(page, clickable({ textContains: 'Yes' }));
}
await page.waitForXPath('//*[@id="signInButton"]', { visible: true });
await page.waitForSelector('xpath///*[@id="signInButton"]', { visible: true });
};

await Promise.all([page.waitForNavigation(), backToTerra()]);
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/register-user.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const testRegisterUserFn = withUser(async ({ page, testUrl, token }) => {

await assertLabelledTextInputValue(page, label({ labelContains: 'Contact Email' }), 'ltcommanderdata@neighborhood.horse');

const registrationEmailDiv = await page.waitForXPath("(//div[.='Email']/following-sibling::div)");
const registrationEmailDiv = await page.waitForSelector("xpath/(//div[.='Email']/following-sibling::div)");
const registrationEmail = registrationEmailDiv?.evaluate((d) => d.value);
const contactEmail = await getLabelledTextInputValue(page, label({ labelContains: 'Contact Email' }));

Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/request-access.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const { registerTest } = require('../utils/jest-utils');
const { withUserToken } = require('../utils/terra-sa-utils');

async function getHrefFromClickable(page, selector) {
return (await (await page.waitForXPath(clickable(selector), _.defaults({ visible: true }))).getProperty('href')).jsonValue();
return (await (await page.waitForSelector(`xpath/${clickable(selector)}`, _.defaults({ visible: true }))).getProperty('href')).jsonValue();
}

const dbGapUrlRoot = 'https://www.ncbi.nlm.nih.gov/projects/gap/cgi-bin/study.cgi?study_id=';
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/run-analysis.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ const testRunAnalysisFn = _.flowRight(
await delay(Millis.ofSeconds(3));
await fillIn(frame, '//textarea', 'print(123456789099876543210990+9876543219)');
await click(frame, clickable({ text: 'Run' }));
await findText(frame, '123456789099886419754209');
await frame.$$('xpath///*[contains(normalize-space(.),"123456789099886419754209")]');

// Save notebook to avoid "unsaved changes" modal when test tear-down tries to close the window
await click(frame, clickable({ text: 'Save and Checkpoint' }));
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/tests/run-rstudio.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const testRunRStudioFn = _.flowRight(
await delay(Millis.ofSeconds(3));
await fillIn(frame, '//textarea', 'x=1;x');
await page.keyboard.press('Enter');
await findText(frame, '[1] 1');
await frame.$$('xpath///*[contains(normalize-space(.),"[1] 1")]');

await dismissInfoNotifications(page);

Expand Down
4 changes: 2 additions & 2 deletions integration-tests/utils/firecloud-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ const selectWorkspace = async (page, billingAccount, workspace) => {
};

const signIntoFirecloud = async (page, token) => {
await page.waitForXPath('//title[text()="FireCloud | Broad Institute"]');
await page.waitForSelector('xpath///title[text()="FireCloud | Broad Institute"]');
await findText(page, 'content you are looking for is currently only accessible');

await page.waitForXPath('//*[@id="sign-in-button"]');
await page.waitForSelector('xpath///*[@id="sign-in-button"]');

/*
* The FireCloud not-signed-in page renders the sign-in button while it is still doing some
Expand Down
66 changes: 27 additions & 39 deletions integration-tests/utils/integration-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const waitForFn = async ({ fn, interval = 2000, timeout = 10000 }) => {
};

const findIframe = async (page, iframeXPath = '//*[@role="main"]/iframe', options) => {
const iframeNode = await page.waitForXPath(iframeXPath, defaultToVisibleTrue(options));
const iframeNode = await page.waitForSelector(`xpath/${iframeXPath}`, defaultToVisibleTrue(options));
const srcHandle = await iframeNode.getProperty('src');
const src = await srcHandle.jsonValue();
const hasFrame = () => page.frames().find((frame) => frame.url().includes(src));
Expand All @@ -53,7 +53,7 @@ const findIframe = async (page, iframeXPath = '//*[@role="main"]/iframe', option
};

const findInGrid = (page, textContains, options) => {
return page.waitForXPath(`//*[@role="table"][contains(normalize-space(.),"${textContains}")]`, defaultToVisibleTrue(options));
return page.waitForSelector(`xpath///*[@role="table"][contains(normalize-space(.),"${textContains}")]`, defaultToVisibleTrue(options));
};

const getClickablePath = (path, text, textContains, isDescendant = false) => {
Expand Down Expand Up @@ -127,26 +127,26 @@ const assertRowHas = async (page, { tableName, expectedColumnValues, withKey: {
const clickTableCell = async (page, { tableName, columnHeader, text, isDescendant = false }, options) => {
const tableCellPath = await getTableCellByContents(page, { tableName, columnHeader, text, isDescendant });
const xpath = `${tableCellPath}[@role="button" or @role="link" or @role="checkbox"]`;
return (await page.waitForXPath(xpath, options)).click();
return (await page.waitForSelector(`xpath/${xpath}`, options)).click();
};

const click = async (page, xpath, options) => {
try {
return (await page.waitForXPath(xpath, defaultToVisibleTrue(options))).click();
return (await page.waitForSelector(`xpath/${xpath}`, defaultToVisibleTrue(options))).click();
} catch (e) {
if (e.message.includes('Node is detached from document')) {
return (await page.waitForXPath(xpath, defaultToVisibleTrue(options))).click();
return (await page.waitForSelector(`xpath/${xpath}`, defaultToVisibleTrue(options))).click();
}
throw e;
}
};

const findText = (page, textContains, options) => {
return page.waitForXPath(`//*[contains(normalize-space(.),"${textContains}")]`, defaultToVisibleTrue(options));
return page.waitForSelector(`xpath///*[contains(normalize-space(.),"${textContains}")]`, defaultToVisibleTrue(options));
};

const getLabelledTextInputValue = async (page, xpath) => {
const inputLabel = await page.waitForXPath(xpath);
const inputLabel = await page.waitForSelector(`xpath/${xpath}`);
const labelFor = await inputLabel?.evaluate((l) => l.getAttribute('for'));
const input = await page.$(`#${labelFor}`);
return await input?.evaluate((i) => i.value);
Expand Down Expand Up @@ -185,7 +185,7 @@ const label = ({ labelContains }) => {
};

const fillIn = async (page, xpath, text, options) => {
const input = await page.waitForXPath(xpath, defaultToVisibleTrue(options));
const input = await page.waitForSelector(`xpath/${xpath}`, defaultToVisibleTrue(options));
await input.click();

// Actually type the text
Expand Down Expand Up @@ -222,15 +222,15 @@ const select = async (page, labelContains, text) => {
};

const waitForNoSpinners = (page, { timeout = 30000 } = {}) => {
return page.waitForXPath('//*[@data-icon="loadingSpinner"]', { hidden: true, timeout });
return page.waitForSelector('xpath///*[@data-icon="loadingSpinner"]', { hidden: true, timeout });
};

const waitForNoModal = (page, { timeout = 30000 } = {}) => {
return page.waitForXPath('//*[contains(@class, "ReactModal__Overlay")]', { hidden: true, timeout });
return page.waitForSelector('.ReactModal__Overlay', { hidden: true, timeout });
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplification

};

const waitForModal = (page, { timeout = 30000 } = {}) => {
return page.waitForXPath('//*[contains(@class, "ReactModal__Overlay")]', { hidden: false, timeout });
return page.waitForSelector('.ReactModal__Overlay', { hidden: false, timeout });
};

// Puppeteer works by internally using MutationObserver. We are setting up the listener before
Expand All @@ -240,7 +240,7 @@ const noSpinnersAfter = async (page, { action, debugMessage, timeout = 30000 })
if (debugMessage) {
console.log(`About to perform an action and wait for spinners. \n\tDebug message: ${debugMessage}`);
}
const foundSpinner = page.waitForXPath('//*[@data-icon="loadingSpinner"]', { timeout });
const foundSpinner = page.waitForSelector('xpath///*[@data-icon="loadingSpinner"]', { timeout });
await Promise.all([foundSpinner, action()]);
return waitForNoSpinners(page, { timeout });
};
Expand All @@ -252,7 +252,7 @@ const delay = (ms) => {
/** Dismiss all popup notifications, including errors. */
const dismissAllNotifications = async (page) => {
await delay(3000); // delayed for any alerts to show
const notificationCloseButtons = await page.$x('(//a | //*[@role="button"] | //button)[contains(@aria-label,"Dismiss")]');
const notificationCloseButtons = await page.$$('xpath/(//a | //*[@role="button"] | //button)[contains(@aria-label,"Dismiss")]');

await Promise.all(notificationCloseButtons.map((handle) => handle.click()));

Expand All @@ -262,8 +262,8 @@ const dismissAllNotifications = async (page) => {
/** Dismiss popup notifications, except for errors. */
const dismissInfoNotifications = async (page) => {
await delay(3000); // delayed for any alerts to show
const notificationCloseButtons = await page.$x(
'(//a | //*[@role="button"] | //button)[contains(@aria-label,"Dismiss") and not(contains(@aria-label,"error"))]'
const notificationCloseButtons = await page.$$(
'xpath/(//a | //*[@role="button"] | //button)[contains(@aria-label,"Dismiss") and not(contains(@aria-label,"error"))]'
);

await Promise.all(notificationCloseButtons.map((handle) => handle.click()));
Expand All @@ -275,14 +275,14 @@ const dismissInfoNotifications = async (page) => {
const dismissNPSSurvey = async (page) => {
let element;
try {
element = await page.waitForXPath('//iframe[@aria-label="NPS Survey"]', { timeout: 1000 });
element = await page.waitForSelector('xpath///iframe[@aria-label="NPS Survey"]', { timeout: 1000 });
} catch (e) {
return; // NPS survey was not found
}
try {
console.log('dismissing NPS survey');
const iframe = await element.contentFrame();
const [closeButton] = await iframe.$x('.//*[normalize-space(.)="Ask Me Later"]');
const [closeButton] = await iframe.$$('xpath/.//*[normalize-space(.)="Ask Me Later"]');
await closeButton.evaluate((button) => button.click());
await delay(500); // delayed for survey to animate off
} catch (e) {
Expand All @@ -297,7 +297,7 @@ const signIntoTerra = async (page, { token, testUrl }) => {
if (testUrl) {
await gotoPage(page, testUrl);
} else {
await page.waitForXPath('//*[contains(normalize-space(.),"Loading Terra")]', { hidden: true });
await page.waitForSelector('xpath///*[contains(normalize-space(.),"Loading Terra")]', { hidden: true });
}

await waitForNoSpinners(page);
Expand All @@ -311,11 +311,7 @@ const signIntoTerra = async (page, { token, testUrl }) => {
};

const findElement = (page, xpath, options) => {
return page.waitForXPath(xpath, defaultToVisibleTrue(options));
};

const findErrorPopup = (page, options) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

findErrorPopup was unused.

return page.waitForXPath('(//a | //*[@role="button"] | //button)[contains(@aria-label,"Dismiss")][contains(@aria-label,"error")]', options);
return page.waitForSelector(`xpath/${xpath}`, defaultToVisibleTrue(options));
};

const heading = ({ level, text, textContains, isDescendant = false }) => {
Expand All @@ -334,7 +330,7 @@ const heading = ({ level, text, textContains, isDescendant = false }) => {
};

const findHeading = (page, xpath, options) => {
return page.waitForXPath(xpath, options);
return page.waitForSelector(`xpath/${xpath}`, options);
};

const svgText = ({ textContains }) => {
Expand All @@ -348,7 +344,7 @@ const navChild = (text) => {
const assertNavChildNotFound = async (page, text) => {
let found = false;
try {
await page.waitForXPath(navChild(text), { timeout: 5 * 1000 });
await page.waitForSelector(`xpath/${navChild(text)}`, { timeout: 5 * 1000 });
found = true;
} catch (e) {}
if (found) {
Expand All @@ -364,25 +360,19 @@ const findInDataTableRow = (page, entityName, text) => {
return findElement(page, elementInDataTableRow(entityName, text));
};

const findButtonInDialogByAriaLabel = (page, ariaLabelText) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused.

return page.waitForXPath(`//*[@role="dialog" and @aria-hidden="false"]//*[@role="button" and contains(@aria-label,"${ariaLabelText}")]`, {
visible: true,
});
};

/** Waits for a menu element to expand (or collapse if isExpanded=false) */
const waitForMenu = (page, { labelContains, isExpanded = true, ...options }) => {
return page.waitForXPath(
`//*[contains(@aria-label,"${labelContains}") or @id=//label[contains(normalize-space(.),"${labelContains}")]/@for or @aria-labelledby=//*[contains(normalize-space(.),"${labelContains}")]/@id][@aria-expanded="${isExpanded}"]`,
defaultToVisibleTrue(options)
);
const labelContainsSelector = `[aria-label*="${labelContains}"], [id="${labelContains}"], [aria-labelledby*="${labelContains}"]`;
const expandedSelector = `[aria-expanded="${isExpanded}"]`;

return page.waitForSelector(`${labelContainsSelector}${expandedSelector}`, defaultToVisibleTrue(options));
};

const openError = async (page) => {
// close out any non-error notifications first
await dismissInfoNotifications(page);

const errorDetails = await page.$x('(//a | //*[@role="button"] | //button)[contains(normalize-space(.),"Details")]');
const errorDetails = await page.$$('xpath/(//a | //*[@role="button"] | //button)[contains(normalize-space(.),"Details")]');

!!errorDetails[0] && (await errorDetails[0].click());

Expand Down Expand Up @@ -526,7 +516,7 @@ const gotoPage = async (page, url) => {
if (httpResponse && !(httpResponse.ok() || httpResponse.status() === 304)) {
throw new Error(`Error loading URL: ${url}. Http response status: ${httpResponse.statusText()}`);
}
await page.waitForXPath('//*[contains(normalize-space(.),"Loading Terra")]', { hidden: true });
await page.waitForSelector('xpath///*[contains(normalize-space(.),"Loading Terra")]', { hidden: true });
} catch (e) {
console.error(e);
// Stop page loading, as if you hit "X" in the browser. ignore exception.
Expand Down Expand Up @@ -610,9 +600,7 @@ module.exports = {
enablePageLogging,
fillIn,
fillInReplace,
findButtonInDialogByAriaLabel,
findElement,
findErrorPopup,
findHeading,
findIframe,
findInDataTableRow,
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/utils/workflow-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const launchWorkflowAndWaitForSuccess = async (page) => {
// stopLoggingPageAjaxResponses()

// If this table doesn't exists, something is wrong. Fail test now.
await page.waitForXPath('//*[@role="table" and @aria-label="submission details"]', { visible: true });
await page.waitForSelector('xpath///*[@role="table" and @aria-label="submission details"]', { visible: true });

// Workflow status list:
// Queued -> Submitted -> Launching -> Running -> Succeeded or Failed
Expand Down
Loading
Loading