foundation.mozilla.org/tests/integration.spec.js

176 строки
6.3 KiB
JavaScript

const { test, expect } = require("@playwright/test");
const waitForImagesToLoad = require("./wait-for-images.js");
test(`Foundation homepage`, async ({ page }, testInfo) => {
page.on(`console`, console.log);
await page.goto(`http://localhost:8000/en/`);
await page.locator(`body.react-loaded`);
await waitForImagesToLoad(page);
// verify newsletter button in the header folds out the newsletter panel
const newsLetterWrapper = page.locator(`#nav-newsletter-form-wrapper`);
expect(await newsLetterWrapper.isVisible()).toBe(false);
const newsLetterButton = page.locator(
`.wide-screen-menu-container button.btn-newsletter`
);
await newsLetterButton.click();
await page.waitForTimeout(500);
expect(await newsLetterWrapper.isVisible()).toBe(true);
// Does the country list show only after we focus on the signup email field?
const countryPicker = await page.locator(
`#nav-newsletter-form-wrapper .country-picker.form-control`
);
const languagePicker = await page.locator(`#userLanguage-header`);
expect(await countryPicker.isVisible()).toBe(false);
expect(await languagePicker.isVisible()).toBe(false);
const input = await page.locator(
`#nav-newsletter-form-wrapper input[name="userEmail"]`
);
await input.focus();
expect(await countryPicker.isVisible()).toBe(true);
expect(await languagePicker.isVisible()).toBe(true);
});
/**
* Perform several PNI tests related to searching/filtering
*
* NOTE: this requires a `new-db` run with the seed value set
* through RANDOM_SEED=530910203 in your .env file
*/
test(`PNI search`, async ({ page }, testInfo) => {
page.on(`console`, console.log);
await page.goto(`http://localhost:8000/en/privacynotincluded`);
await page.locator(`body.react-loaded`);
await waitForImagesToLoad(page);
const searchTerm = "ab";
const counts = {
// provided RANDOM_SEED=530910203 was used!
total: 42,
health: 13,
smart: 5,
percy: 1,
searchTerm: 4,
searchTermWithDing: 2,
};
const qs = {
ding: `#product-filter-pni-toggle`,
dingLabel: `label[for="product-filter-pni-toggle"]`,
products: `.product-box.d-flex`,
searchBar: `#product-filter-search-input`,
clearSearch: `label[for="product-filter-search-input"]`,
activeCategory: `#multipage-nav a.multipage-link.active`,
activeSubCategory: `a.subcategories.active`,
healthCategory: `#multipage-nav a.multipage-link[data-name="Health & Exercise"]`,
};
let products, activeCategory;
// verify that the PNI "ding" is not selected on initial load
const ding = page.locator(qs.ding);
await expect(ding).not.toBeChecked();
// Baseline product count test
products = page.locator(qs.products);
await expect(products).toHaveCount(counts.total);
// Verify that all products are sorted on creepiness
expect(await confirmSorted(page)).toBe(true);
// Test search filtering for "percy": there should be two products
const searchBar = page.locator(qs.searchBar);
await searchBar.type("percy");
products = page.locator(qs.products);
await expect(products).toHaveCount(counts.percy);
// And we should be back to the original number when clearing search.
await page.click(qs.clearSearch);
products = page.locator(qs.products);
await expect(products).toHaveCount(counts.total);
// Click through to the Health & Exercise category and
// verify the correct number of products show up.
await page.click(qs.healthCategory);
activeCategory = page.locator(qs.activeCategory);
await expect(activeCategory).toHaveAttribute(
`data-name`,
`Health & Exercise`
);
products = page.locator(qs.products);
await expect(products).toHaveCount(counts.health);
// Select a known subcategory and verify the correct
// number of products show up.
subcats = page.locator(`a.subcategories`);
await expect(subcats).toHaveCount(3);
subcat = page.locator(`a.subcategories:nth-child(2)`);
await expect(subcat).toHaveText(`Smart Scales`);
await page.click(`a.subcategories:nth-child(2)`);
products = page.locator(qs.products);
await expect(products).toHaveCount(counts.smart);
// Filter for "percy" products: there should be two, and the active
// category should be "all" while search filtering
await searchBar.type("percy");
products = page.locator(qs.products);
await expect(products).toHaveCount(counts.percy);
activeCategory = page.locator(qs.activeCategory);
await expect(activeCategory).toHaveAttribute(`data-name`, `None`);
// Clear the search bar: original subcategory should be "active"
await page.click(qs.clearSearch);
activeCategory = page.locator(qs.activeCategory);
await expect(activeCategory).toHaveAttribute(
`data-name`,
`Health & Exercise`
);
activeSubCat = page.locator(qs.activeSubCategory);
await expect(activeSubCat).toHaveText(`Smart Scales`);
products = page.locator(qs.products);
await expect(products).toHaveCount(counts.smart);
// Clicking the subcategory should restore the parent category
await page.click(qs.activeSubCategory);
products = page.locator(qs.products);
await expect(products).toHaveCount(counts.health);
// Filtering for "ding" should refocus on text field if there
// was a search term, while filtering for ding-only
await searchBar.type(searchTerm);
await page.click(`main`);
await page.click(qs.dingLabel);
await expect(searchBar).toBeFocused();
// have to check for the ding-only products here,
// since the ding - only class is added to a parent element
products = page.locator(".product-box:visible");
await expect(products).toHaveCount(counts.searchTermWithDing);
await page.click(qs.dingLabel);
products = page.locator(qs.products);
await expect(products).toHaveCount(counts.searchTerm);
// Finally, verify that all products are still sorted
await page.click(qs.clearSearch);
expect(await confirmSorted(page)).toBe(true);
});
/**
* Helper function for PNI search/filter tests.
* Confirms whether or not all products are sorted by creepiness
* @param {Page} page The Playwright page handle
*/
async function confirmSorted(page) {
return page.evaluate(() => {
const products = [...document.querySelectorAll(`.product-box`)];
return products.every((e, i, list, a, b) => {
if (i === 0) return true;
a = parseFloat(list[i - 1].dataset.creepiness);
b = parseFloat(e.dataset.creepiness);
return b >= a;
});
});
}