Skip to content

Commit 406f860

Browse files
committed
fix: made backpages test work with nTag cells (#4080)
1 parent 7cc24c2 commit 406f860

File tree

3 files changed

+84
-28
lines changed

3 files changed

+84
-28
lines changed

explorer/e2e/anvil/anvil-tabs.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,16 @@ const anvilDatasetsPreselectedColumns = [
2929
{ name: "Data Modality", sortable: true },
3030
];
3131
const anvilDatasetsSelectableColumns = [
32-
{ name: "Phenotypic Sex", sortable: true },
33-
{ name: "Reported Ethnicity", sortable: true },
32+
{
33+
name: "Phenotypic Sex",
34+
pluralizedLabel: "phenotypic sexes",
35+
sortable: true,
36+
},
37+
{
38+
name: "Reported Ethnicity",
39+
pluralizedLabel: "reported ethnicities",
40+
sortable: true,
41+
},
3442
];
3543

3644
export const anvilTabs: AnvilCMGTabCollection = {
@@ -63,8 +71,16 @@ export const anvilTabs: AnvilCMGTabCollection = {
6371
{ name: "Dataset", sortable: true },
6472
],
6573
selectableColumns: [
66-
{ name: "Phenotypic Sex", sortable: true },
67-
{ name: "Reported Ethnicity", sortable: true },
74+
{
75+
name: "Phenotypic Sex",
76+
pluralizedLabel: "phenotypic sexes",
77+
sortable: true,
78+
},
79+
{
80+
name: "Reported Ethnicity",
81+
pluralizedLabel: "reported ethnicities",
82+
sortable: true,
83+
},
6884
],
6985
tabName: "BioSamples",
7086
url: "/biosamples",
@@ -103,6 +119,7 @@ export const anvilTabs: AnvilCMGTabCollection = {
103119
correspondingColumn: anvilDatasetsPreselectedColumns[6],
104120
name: "Data modality",
105121
},
122+
// Skipped the below two columns, since they aren't always readable
106123
{
107124
correspondingColumn: anvilDatasetsSelectableColumns[0],
108125
name: "Phenotypic sex",

explorer/e2e/testFunctions.ts

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { BrowserContext, expect, Locator, Page } from "@playwright/test";
2-
import { backpageHeader, TabDescription } from "./testInterfaces";
2+
import {
3+
BackpageHeader,
4+
ColumnDescription,
5+
TabDescription,
6+
} from "./testInterfaces";
37

48
/* eslint-disable sonarjs/no-duplicate-string -- ignoring duplicate strings here */
59

@@ -471,9 +475,7 @@ export async function testExportBackpage(
471475
await expect(firstButtonLocator).toBeEnabled();
472476
// Select all checkboxes on the pages
473477
const checkboxLocators = await page.getByRole("checkbox").all();
474-
console.log(checkboxLocators);
475478
for (const checkboxLocator of checkboxLocators) {
476-
console.log(checkboxLocator);
477479
if (!(await checkboxLocator.isChecked())) {
478480
await checkboxLocator.click();
479481
await expect(checkboxLocator).toBeChecked();
@@ -570,13 +572,43 @@ export async function testBackpageAccess(
570572
).toBeVisible();
571573
}
572574

575+
const hoverAndGetText = async (
576+
page: Page,
577+
columnDescription: ColumnDescription | undefined,
578+
rowPosition: number,
579+
columnPosition: number
580+
): Promise<string> => {
581+
const cellLocator = getNthElementTextLocator(
582+
page,
583+
rowPosition,
584+
columnPosition
585+
);
586+
const cellText = await cellLocator.innerText();
587+
588+
if (
589+
columnDescription != undefined &&
590+
columnDescription.pluralizedLabel != undefined &&
591+
RegExp("\\s*[0-9]+ " + columnDescription.pluralizedLabel + "\\s*").test(
592+
cellText
593+
)
594+
) {
595+
await cellLocator.locator("*").last().hover();
596+
await page.getByRole("tooltip").waitFor();
597+
const outputText = (await page.getByRole("tooltip").innerText()).trim();
598+
await page.getByRole("columnheader").first().hover();
599+
await expect(page.getByRole("tooltip")).toHaveCount(0);
600+
return outputText;
601+
}
602+
return cellText.trim();
603+
};
604+
573605
export async function testBackpageDetails(
574606
page: Page,
575607
tab: TabDescription
576608
): Promise<void> {
577609
if (tab.backpageHeaders == null) {
578610
await expect(false);
579-
return; // This is unreachable, but typescript doesn't know without it
611+
return; // This is unreachable due to the expect, but typescript doesn't know
580612
}
581613
await page.goto(tab.url);
582614
// Enable test columns
@@ -585,33 +617,39 @@ export async function testBackpageDetails(
585617
const combinedColumns = tab.preselectedColumns.concat(tab.selectableColumns);
586618
const filterString = (x: string | undefined): x is string => x !== undefined;
587619
// Get the columns that correspond with a header on the backpage details
588-
const headerCorrespondingColumns: string[] = tab.backpageHeaders
620+
const backpageCorrespondingColumns: string[] = tab.backpageHeaders
589621
.map((header) => header?.correspondingColumn?.name)
590622
.filter(filterString)
591623
.map((x) => x.trim());
592624
for (let i = 0; i < combinedColumns.length; i++) {
593-
const headerColumnText = (
625+
// Get the name of the current column
626+
const columnHeaderName = (
594627
await page.getByRole("columnheader").nth(i).innerText()
595628
).trim();
596-
if (headerCorrespondingColumns.includes(headerColumnText)) {
597-
const headerEntryText = await getNthElementTextLocator(
598-
page,
599-
1,
600-
i
601-
).innerText();
629+
// If the selected column has an entry on the backpage
630+
if (backpageCorrespondingColumns.includes(columnHeaderName)) {
631+
// Get the object of the current column (we have to do it this way, because the combinedColumn list is not ordered)
632+
const columnObject = combinedColumns.find(
633+
(x) => x.name == columnHeaderName
634+
);
635+
// Get the entry text
636+
const tableEntryText = await hoverAndGetText(page, columnObject, 0, i);
637+
// Get the name of the corresponding header on the backpage
602638
const correspondingHeaderName = tab.backpageHeaders.find(
603-
(header: backpageHeader) =>
604-
header?.correspondingColumn?.name === headerColumnText
639+
(header: BackpageHeader) =>
640+
header?.correspondingColumn?.name === columnHeaderName
605641
)?.name;
606642
if (correspondingHeaderName === undefined) {
607643
// Fail the test, because this means there is an incorrect configuraiton in the tab definition
608644
await expect(false);
609645
return;
610646
}
611-
headers.push({ header: correspondingHeaderName, value: headerEntryText });
647+
headers.push({ header: correspondingHeaderName, value: tableEntryText });
612648
}
613649
}
614-
await getNthElementTextLocator(page, 1, 0).click();
650+
// Go to the backpage
651+
await getNthElementTextLocator(page, 0, 0).click();
652+
// Expect the details name to be visible
615653
await expect(
616654
page.getByText(tab.backpageExportButtons?.detailsName ?? "ERROR")
617655
).toBeVisible();

explorer/e2e/testInterfaces.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
export interface TabDescription {
2-
backpageExportButtons?: backpageExportButtons;
3-
backpageHeaders?: backpageHeader[];
2+
backpageExportButtons?: BackpageExportButtons;
3+
backpageHeaders?: BackpageHeader[];
44
emptyFirstColumn: boolean;
5-
preselectedColumns: columnDescription[];
6-
selectableColumns: columnDescription[];
5+
preselectedColumns: ColumnDescription[];
6+
selectableColumns: ColumnDescription[];
77
tabName: string;
88
url: string;
99
}
@@ -24,17 +24,18 @@ export interface AnvilCatalogTabCollection {
2424

2525
export type TabCollectionKeys = keyof AnvilCMGTabCollection;
2626

27-
export interface columnDescription {
27+
export interface ColumnDescription {
2828
name: string;
29+
pluralizedLabel?: string;
2930
sortable: boolean;
3031
}
3132

32-
export interface backpageHeader {
33-
correspondingColumn?: columnDescription;
33+
export interface BackpageHeader {
34+
correspondingColumn?: ColumnDescription;
3435
name: string;
3536
}
3637

37-
export interface backpageExportButtons {
38+
export interface BackpageExportButtons {
3839
accessNotGrantedMessage: string;
3940
detailsName: string;
4041
exportTabName: string;

0 commit comments

Comments
 (0)