|
1 | | -import test from "@playwright/test"; |
2 | | -import { |
3 | | - testBulkDownloadIndexExportWorkflow, |
4 | | - testIndexExportSummary, |
5 | | -} from "../testFunctions"; |
| 1 | +import test, { ElementHandle, Response, Page } from "@playwright/test"; |
| 2 | +import { expect } from "@playwright/test"; |
| 3 | +import { testBulkDownloadIndexExportWorkflow } from "../testFunctions"; |
6 | 4 | import { ANVIL_TABS } from "./anvil-tabs"; |
| 5 | +import { MUI_CLASSES, TEST_IDS } from "../features/common/constants"; |
7 | 6 |
|
8 | | -test("Smoke test File Manifest Request index export workflow on the Files tab", async ({ |
9 | | - page, |
10 | | -}) => { |
11 | | - test.setTimeout(120000); |
12 | | - const testResult = await testBulkDownloadIndexExportWorkflow( |
| 7 | +test.describe("AnVIL Data Explorer Export", () => { |
| 8 | + test("Smoke test File Manifest Request index export workflow on the Files tab", async ({ |
13 | 9 | page, |
14 | | - ANVIL_TABS.FILES |
15 | | - ); |
16 | | - if (!testResult) { |
17 | | - test.fail(); |
18 | | - } |
19 | | -}); |
| 10 | + }) => { |
| 11 | + test.setTimeout(120000); |
| 12 | + const testResult = await testBulkDownloadIndexExportWorkflow( |
| 13 | + page, |
| 14 | + ANVIL_TABS.FILES |
| 15 | + ); |
| 16 | + if (!testResult) { |
| 17 | + test.fail(); |
| 18 | + } |
| 19 | + }); |
| 20 | + |
| 21 | + test("Verifies that the Selected Data Summary on the export page displays the same label and count as the summary on the BioSamples tab", async ({ |
| 22 | + page, |
| 23 | + }) => { |
| 24 | + await page.goto("/biosamples"); |
| 25 | + await page.waitForURL(/\/biosamples/); |
| 26 | + await Promise.all([waitForTestId(page, TEST_IDS.ENTITY_SUMMARY)]); |
| 27 | + |
| 28 | + // Export button should be visible. |
| 29 | + const button = page.getByTestId(TEST_IDS.EXPORT_BUTTON); |
| 30 | + await expect(button).toBeVisible(); |
| 31 | + |
| 32 | + // Summary should be visible. |
| 33 | + const summaryLocator = page.getByTestId(TEST_IDS.ENTITY_SUMMARY); |
| 34 | + await expect(summaryLocator).toBeVisible(); |
| 35 | + |
| 36 | + // Get each summary span's inner text. |
| 37 | + const innerTexts = await summaryLocator |
| 38 | + .locator(MUI_CLASSES.TYPOGRAPHY) // Retrieves the count and label and omits the dot separator. |
| 39 | + .allTextContents(); |
20 | 40 |
|
21 | | -test("Check that figures in the Selected Data Summary tab on the index export page matches figures on the index page on the BioSamples tab", async ({ |
22 | | - page, |
23 | | -}) => { |
24 | | - const testResult = await testIndexExportSummary(page, ANVIL_TABS.BIOSAMPLES); |
25 | | - if (!testResult) { |
26 | | - test.fail(); |
27 | | - } |
| 41 | + // Pair each summary item's label and count by iterating through the text contents |
| 42 | + // two at a time, and store them as [label, count] tuples in the summary array. |
| 43 | + const summary: [string, string][] = []; |
| 44 | + for (let i = 0; i < innerTexts.length; i += 2) { |
| 45 | + summary.push([innerTexts[i + 1], innerTexts[i]]); |
| 46 | + } |
| 47 | + |
| 48 | + // Click the export button and wait for the summary API to be called. |
| 49 | + await Promise.all([ |
| 50 | + button.click(), |
| 51 | + page.waitForURL(/\/export/), |
| 52 | + page.waitForResponse(urlOrPredicate), |
| 53 | + waitForTestId(page, TEST_IDS.EXPORT_SUMMARY), |
| 54 | + ]); |
| 55 | + |
| 56 | + // Export summary should be visible. |
| 57 | + const exportSummaryLocator = page.getByTestId(TEST_IDS.EXPORT_SUMMARY); |
| 58 | + await expect(exportSummaryLocator).toBeVisible(); |
| 59 | + |
| 60 | + // Test that each summary item is present in the export summary |
| 61 | + // with corresponding count. |
| 62 | + for (const [label, count] of summary) { |
| 63 | + const summaryItem = exportSummaryLocator |
| 64 | + .locator("> div") |
| 65 | + .filter({ hasText: label }); |
| 66 | + await expect(summaryItem).toBeVisible(); |
| 67 | + await expect(summaryItem).toContainText(count, { timeout: 5000 }); |
| 68 | + } |
| 69 | + }); |
28 | 70 | }); |
| 71 | + |
| 72 | +/** |
| 73 | + * Checks if the response is the index summary API. |
| 74 | + * @param r - Response. |
| 75 | + * @returns boolean. |
| 76 | + */ |
| 77 | +function urlOrPredicate(r: Response): boolean { |
| 78 | + return r.url().includes("/index/summary") && r.status() === 200; |
| 79 | +} |
| 80 | + |
| 81 | +/** |
| 82 | + * Waits for a locator to be visible. |
| 83 | + * @param page - Page. |
| 84 | + * @param testId - Test ID. |
| 85 | + * @returns Promise<void>. |
| 86 | + */ |
| 87 | +function waitForTestId( |
| 88 | + page: Page, |
| 89 | + testId: string |
| 90 | +): Promise<ElementHandle<HTMLElement | SVGElement>> { |
| 91 | + return page.waitForSelector(`[data-testid="${testId}"]`, { |
| 92 | + state: "visible", |
| 93 | + }); |
| 94 | +} |
0 commit comments