1510-smoke-test (#1548)

* 1510-smoke-test

* config default

* update tests

* update test config

* fix linter errors

* more comments

* address comments

* use npm install in push_tests.yml

* use environment.default.json

* adding docs

* Take care of @mweiden's nits

* Save screenshots in the __tests__/screenshots/ directory

* typo

* docs

* Add chart tests (#1580)

* merge tests

* check if bin creation returned null before rendering charts (#1576)

* check if bin creation returned null before rendering charts

* refactor chart rendering into functions (#1577)

* little fixes from PR

* reintroduce fix to check for null values

* change getAllByClass to return element

* slice instead

* new stackedbar test

* feedback-1573-test (#1579)

* feedback-1573-test

* enable whole test set

* revert tests

Co-authored-by: Timmy Huang <tihuan@users.noreply.github.com>

* tweak test to actually render chart

* include snapshot

* remove async

* fix getAllHistograms

* properly grab id

Co-authored-by: Timmy Huang <tihuan@users.noreply.github.com>

Co-authored-by: Matt Weiden <538456+mweiden@users.noreply.github.com>
Co-authored-by: Severiano Badajoz <sbadajoz@chanzuckerberg.com>
This commit is contained in:
Timmy Huang
2020-06-24 11:45:39 -07:00
committed by GitHub
co-authored by Matt Weiden Severiano Badajoz
parent e22e671f10
commit 83376627e8
42 changed files with 1388 additions and 887 deletions
+121 -63
View File
@@ -1,73 +1,131 @@
const puppeteerUtils = (page) => ({
waitByID(testId, props = {}) {
return page.waitForSelector(`[data-testid='${testId}']`, props);
},
/* eslint-disable no-await-in-loop -- await in loop is needed to emulate sequential user actions */
export function getTestId(id) {
return `[data-testid='${id}']`;
}
waitByClass(testClass, props = {}) {
return page.waitForSelector(`[data-testclass='${testClass}']`, props);
},
export function getTestClass(className) {
return `[data-testclass='${className}']`;
}
async waitForAllByIds(testIds, props = {}) {
return Promise.all(
testIds.map((testId) =>
page.waitForSelector(`[data-testid='${testId}']`, props)
)
);
},
export async function waitByID(testId, props = {}) {
return page.waitForSelector(getTestId(testId), props);
}
async getAllByClass(testClass) {
return page.$$eval(`[data-testclass=${testClass}]`, (eles) =>
eles.map((ele) => ele.dataset.testid)
);
},
export async function waitByClass(testClass, props = {}) {
await page.waitForSelector(`[data-testclass='${testClass}']`, props);
}
async typeInto(testId, text) {
// blueprint's typeahead is treating typing weird, clicking & waiting first solves this
// only works for text without special characters
await this.waitByID(testId);
const selector = `[data-testid='${testId}']`;
// type ahead can be annoying if you don't pause before you type
await page.click(selector);
await page.waitFor(200);
await page.type(selector, text);
},
export async function waitForAllByIds(testIds) {
await Promise.all(
testIds.map((testId) => page.waitForSelector(getTestId(testId)))
);
}
async clearInputAndTypeInto(testId, text) {
await this.waitByID(testId);
const selector = `[data-testid='${testId}']`;
// only works for text without special characters
// type ahead can be annoying if you don't pause before you type
await page.click(selector);
await page.waitFor(200);
// select all
await page.click(selector, { clickCount: 3 });
await page.keyboard.press("Backspace");
await page.type(selector, text);
},
export async function getAllByClass(testClass) {
return page.$$(`[data-testclass=${testClass}]`);
}
async clickOn(testid, options = {}) {
await this.waitByID(testid, options);
const click = await page.click(`[data-testid='${testid}']`);
await page.waitFor(50);
return click;
},
export async function typeInto(testId, text) {
// blueprint's typeahead is treating typing weird, clicking & waiting first solves this
// only works for text without special characters
await waitByID(testId);
const selector = getTestId(testId);
// type ahead can be annoying if you don't pause before you type
await page.click(selector);
await page.waitFor(200);
await page.type(selector, text);
}
async getOneElementInnerHTML(selector, options = {}) {
await page.waitForSelector(selector, options);
return page.$eval(selector, (el) => el.innerHTML);
},
export async function clearInputAndTypeInto(testId, text) {
await waitByID(testId);
const selector = getTestId(testId);
// only works for text without special characters
// type ahead can be annoying if you don't pause before you type
await page.click(selector);
await page.waitFor(200);
// select all
await page.click(selector, { clickCount: 3 });
await page.keyboard.press("Backspace");
await page.type(selector, text);
}
async getOneElementInnerText(selector) {
await page.waitForSelector(selector);
return page.$eval(selector, (el) => el.innerText);
},
export async function clickOn(testId, options = {}) {
await expect(page).toClick(getTestId(testId), options);
}
async getElementCoordinates(testid) {
return page.$eval(`[data-testid='${testid}']`, (elem) => {
const { left, top } = elem.getBoundingClientRect();
return [left, top];
});
},
});
/**
* (thuang): There are times when Puppeteer clicks on a button and the page doesn't respond.
* So I added clickOnUntil() to retry clicking until a given condition is met.
*/
export async function clickOnUntil(testId, assert) {
const MAX_RETRY = 10;
const WAIT_FOR_MS = 200;
export default puppeteerUtils;
let retry = 0;
while (retry < MAX_RETRY) {
try {
await clickOn(testId);
await assert();
break;
} catch (error) {
retry += 1;
await page.waitFor(WAIT_FOR_MS);
}
}
if (retry === MAX_RETRY) {
throw Error("clickOnUntil() assertion failed!");
}
}
export async function getOneElementInnerHTML(selector, options = {}) {
await page.waitForSelector(selector, options);
return page.$eval(selector, (el) => el.innerHTML);
}
export async function getOneElementInnerText(selector) {
expect(page).toMatchElement(selector);
return page.$eval(selector, (el) => el.innerText);
}
export async function getElementCoordinates(testId) {
return page.$eval(getTestId(testId), (elem) => {
const { left, top } = elem.getBoundingClientRect();
return [left, top];
});
}
async function clickTermsOfService() {
if (!(await isElementPresent(getTestId("tos-cookies-accept")))) return;
await clickOn("tos-cookies-accept");
}
async function nameNewAnnotation() {
if (await isElementPresent(getTestId("annotation-dialog"))) {
await typeInto("new-annotation-name", "ignoreE2E");
await clickOn("submit-annotation");
// wait for the page to load
await waitByClass("autosave-complete");
}
}
export async function goToPage(url) {
await page.goto(url, {
waitUntil: "networkidle0",
});
await nameNewAnnotation();
await clickTermsOfService();
}
export async function isElementPresent(selector, options) {
return Boolean(await page.$(selector, options));
}
/* eslint-enable no-await-in-loop -- await in loop is needed to emulate sequential user actions */