Skip to content

Commit 1cc23bd

Browse files
committed
feat: first draft of backpage details tab - fails on Webkit (#4080)
1 parent 8289093 commit 1cc23bd

File tree

4 files changed

+175
-23
lines changed

4 files changed

+175
-23
lines changed
Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,31 @@
11
import { test } from "@playwright/test";
2-
import { testExportBackpage } from "../testFunctions";
2+
import {
3+
testBackpageAccess,
4+
testBackpageDetails,
5+
testExportBackpage,
6+
} from "../testFunctions";
37
import { anvilTabs } from "./anvil-tabs";
48
test("Smoke test `Export to Terra` button on the first available dataset", async ({
59
context,
610
page,
711
}) => {
12+
test.setTimeout(120000);
813
await testExportBackpage(context, page, anvilTabs.datasets);
914
});
15+
16+
test("Check access controls on the datasets backpages work for the first two tabs", async ({
17+
page,
18+
}) => {
19+
test.setTimeout(120000);
20+
await testBackpageAccess(page, anvilTabs.datasets);
21+
});
22+
23+
test("Check that information on the backpages matches information in the data tables", async ({
24+
page,
25+
}) => {
26+
test.setTimeout(120000);
27+
const passed = await testBackpageDetails(page, anvilTabs.datasets);
28+
if (!passed) {
29+
test.fail();
30+
}
31+
});

explorer/e2e/anvil/anvil-tabs.ts

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ export const anvilFilters: string[] = [
1919
"Reported Ethnicity",
2020
];
2121

22+
const anvilDatasetsPreselectedColumns = [
23+
{ name: "Dataset", sortable: true },
24+
{ name: "Access", sortable: false },
25+
{ name: "Identifier", sortable: true },
26+
{ name: "Consent Group", sortable: true },
27+
{ name: "Organism Type", sortable: true },
28+
{ name: "Diagnosis", sortable: true },
29+
{ name: "Data Modality", sortable: true },
30+
];
31+
const anvilDatasetsSelectableColumns = [
32+
{ name: "Phenotypic Sex", sortable: true },
33+
{ name: "Reported Ethnicity", sortable: true },
34+
];
35+
2236
export const anvilTabs: AnvilCMGTabCollection = {
2337
activities: {
2438
emptyFirstColumn: false,
@@ -56,20 +70,38 @@ export const anvilTabs: AnvilCMGTabCollection = {
5670
url: "/biosamples",
5771
},
5872
datasets: {
59-
emptyFirstColumn: false,
60-
preselectedColumns: [
61-
{ name: "Dataset", sortable: true },
62-
{ name: "Access", sortable: false },
63-
{ name: "Identifier", sortable: true },
64-
{ name: "Consent Group", sortable: true },
65-
{ name: "Organism Type", sortable: true },
66-
{ name: "Diagnosis", sortable: true },
67-
{ name: "Data Modality", sortable: true },
68-
],
69-
selectableColumns: [
70-
{ name: "Phenotypic Sex", sortable: true },
71-
{ name: "Reported Ethnicity", sortable: true },
73+
backpageHeaders: [
74+
{
75+
name: "Dataset ID",
76+
},
77+
{
78+
correspondingColumn: anvilDatasetsPreselectedColumns[3],
79+
name: "Consent group",
80+
},
81+
{
82+
correspondingColumn: anvilDatasetsPreselectedColumns[4],
83+
name: "Organism type",
84+
},
85+
{
86+
correspondingColumn: anvilDatasetsPreselectedColumns[5],
87+
name: "Diagnosis",
88+
},
89+
{
90+
correspondingColumn: anvilDatasetsPreselectedColumns[6],
91+
name: "Data modality",
92+
},
93+
{
94+
correspondingColumn: anvilDatasetsSelectableColumns[0],
95+
name: "Phenotypic sex",
96+
},
97+
{
98+
correspondingColumn: anvilDatasetsSelectableColumns[1],
99+
name: "Reported ethnicity",
100+
},
72101
],
102+
emptyFirstColumn: false,
103+
preselectedColumns: anvilDatasetsPreselectedColumns,
104+
selectableColumns: anvilDatasetsSelectableColumns,
73105
tabName: "Datasets",
74106
url: "/datasets",
75107
},

explorer/e2e/testFunctions.ts

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { BrowserContext, expect, Locator, Page } from "@playwright/test";
2-
import { TabDescription } from "./testInterfaces";
2+
import { backpageHeader, TabDescription } from "./testInterfaces";
33

44
/* eslint-disable sonarjs/no-duplicate-string -- ignoring duplicate strings here */
55

@@ -432,6 +432,14 @@ export async function testClearAll(
432432
}
433433
}
434434

435+
const getRowLocatorByAccess = (page: Page, access: string): Locator =>
436+
page
437+
.getByRole("row")
438+
.filter({ has: page.getByRole("cell", { name: access }) })
439+
.first()
440+
.getByRole("cell")
441+
.first();
442+
435443
// Backpages tests
436444
export async function testExportBackpage(
437445
context: BrowserContext,
@@ -442,12 +450,7 @@ export async function testExportBackpage(
442450
await page.goto(tab.url);
443451
await expect(getFirstElementTextLocator(page, 1)).toBeVisible();
444452
// Expect to find row with a granted status indicator
445-
const granted_row_locator = await page
446-
.getByRole("row")
447-
.filter({ has: page.getByRole("cell", { name: "Granted" }) })
448-
.first()
449-
.getByRole("cell")
450-
.first();
453+
const granted_row_locator = getRowLocatorByAccess(page, "Granted");
451454
await expect(granted_row_locator).toBeVisible();
452455
// Click into the selected row
453456
await granted_row_locator.click();
@@ -478,7 +481,7 @@ export async function testExportBackpage(
478481
).toBeVisible();
479482
await expect(
480483
page.getByText("Your Terra Workspace Link is Ready", { exact: true })
481-
).toBeVisible({ timeout: 30000 });
484+
).toBeVisible({ timeout: 60000 });
482485
const openTerraButton = page.getByRole("button", { name: "Open Terra" });
483486
await expect(openTerraButton).toBeEnabled();
484487
// Click the "Open Terra" Button and await a new browser tab
@@ -487,8 +490,97 @@ export async function testExportBackpage(
487490
const newPage = await pagePromise;
488491
// Expect the new browser tab to look like the Terra page
489492
await expect(
490-
newPage.getByText("Welcome to Terra Community Workbench")
493+
newPage.getByText(
494+
"If you are a new user or returning user, click sign in to continue."
495+
)
491496
).toBeVisible();
492497
}
493498

499+
export async function testBackpageAccess(
500+
page: Page,
501+
tab: TabDescription
502+
): Promise<void> {
503+
// Goto the specified tab
504+
await page.goto(tab.url);
505+
// Check that the first "Granted" tab has access granted
506+
const grantedRowLocator = getRowLocatorByAccess(page, "Granted");
507+
await expect(grantedRowLocator).toBeVisible();
508+
await grantedRowLocator.click();
509+
await expect(page.getByText("Access Granted")).toBeVisible();
510+
await page.getByText("Export", { exact: true }).click();
511+
await expect(page).toHaveURL(/\.*\/export-to-terra/);
512+
await expect(page.getByRole("checkbox").first()).toBeVisible();
513+
const requestLinkButtonLocator = page.getByRole("button", {
514+
name: "Request Link",
515+
});
516+
await expect(requestLinkButtonLocator).toBeEnabled();
517+
// Go back to the table page
518+
await page.getByRole("link", { name: "Datasets" }).click();
519+
// Check that the first "Required" tab does not have access granted
520+
const requiredRowLocator = getRowLocatorByAccess(page, "Required");
521+
await expect(requiredRowLocator).toBeVisible();
522+
await requiredRowLocator.click();
523+
await expect(page.getByText("Access Required")).toBeVisible();
524+
await page.getByText("Export", { exact: true }).click();
525+
await expect(page).toHaveURL(/\.*\/export-to-terra/);
526+
await expect(
527+
page.getByText(
528+
"To export this dataset, please sign in and, if necessary, request access.",
529+
{ exact: true }
530+
)
531+
).toBeVisible();
532+
}
533+
534+
export async function testBackpageDetails(
535+
page: Page,
536+
tab: TabDescription
537+
): Promise<boolean> {
538+
if (tab?.backpageHeaders === undefined) {
539+
return false;
540+
}
541+
await page.goto(tab.url);
542+
// Enable test columns
543+
await testSelectableColumns(page, tab); //TODO: check if this funtion breaks if selectable columns don't load in order
544+
const headers: { header: string; value: string }[] = [];
545+
const combinedColumns = tab.preselectedColumns.concat(tab.selectableColumns);
546+
const filterString = (x: string | undefined): x is string => x !== undefined;
547+
const headerCorrespondingColumns: string[] = tab.backpageHeaders
548+
.map((header) => header?.correspondingColumn?.name)
549+
.filter(filterString)
550+
.map((x) => x.trim());
551+
console.log(headerCorrespondingColumns);
552+
for (let i = 0; i < combinedColumns.length; i++) {
553+
const headerColumnText = (
554+
await page.getByRole("columnheader").nth(i).innerText()
555+
).trim();
556+
if (headerCorrespondingColumns.includes(headerColumnText)) {
557+
const headerEntryText = await getNthElementTextLocator(
558+
page,
559+
2,
560+
i
561+
).innerText();
562+
const correspondingHeaderName = tab.backpageHeaders.find(
563+
(header: backpageHeader) =>
564+
header?.correspondingColumn?.name === headerColumnText
565+
)?.name;
566+
if (correspondingHeaderName === undefined) {
567+
return false;
568+
}
569+
headers.push({ header: correspondingHeaderName, value: headerEntryText });
570+
}
571+
}
572+
await getNthElementTextLocator(page, 2, 0).click();
573+
await expect(page.getByText("Dataset Details")).toBeVisible();
574+
for (const headerValue of headers) {
575+
await expect(
576+
page
577+
.locator(
578+
`:text('${headerValue.value}'):below(:text('${headerValue.header}'))`
579+
)
580+
.first()
581+
).toBeVisible();
582+
}
583+
return true;
584+
}
585+
494586
/* eslint-enable sonarjs/no-duplicate-string -- Checking duplicate strings again*/

explorer/e2e/testInterfaces.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export interface TabDescription {
2+
backpageHeaders?: backpageHeader[];
23
emptyFirstColumn: boolean;
34
preselectedColumns: columnDescription[];
45
selectableColumns: columnDescription[];
@@ -26,3 +27,8 @@ export interface columnDescription {
2627
name: string;
2728
sortable: boolean;
2829
}
30+
31+
export interface backpageHeader {
32+
correspondingColumn?: columnDescription;
33+
name: string;
34+
}

0 commit comments

Comments
 (0)