Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 0 additions & 49 deletions integration-tests/tests/pages/CliPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,62 +210,13 @@ export class CliPage {
);
}

/**
* Set default organism
*/
async setDefaultOrganism(organism: string): Promise<CliResult> {
return this.execute(['organism', 'select', organism]);
}

/**
* Set default group
*/
async setDefaultGroup(groupId: number): Promise<CliResult> {
return this.execute(['group', 'select', groupId.toString()]);
}

/**
* Clear default organism
*/
async clearDefaultOrganism(): Promise<CliResult> {
return this.execute(['organism', 'select', '--none']);
}

/**
* Clear default group
*/
async clearDefaultGroup(): Promise<CliResult> {
return this.execute(['group', 'select', '--none']);
}

/**
* Get available organisms
*/
async getAvailableOrganisms(): Promise<CliResult> {
return this.execute(['organism', 'list']);
}

/**
* Get available groups
*/
async getAvailableGroups(): Promise<CliResult> {
return this.execute(['group', 'list']);
}

/**
* Login with username and password
*/
async login(username: string, password: string): Promise<CliResult> {
return this.execute(['auth', 'login', '--username', username, '--password', password]);
}

/**
* Check authentication status
*/
async authStatus(): Promise<CliResult> {
return this.execute(['auth', 'status']);
}

/**
* Logout
*/
Expand Down
15 changes: 15 additions & 0 deletions integration-tests/tests/pages/edit.page.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { expect, Page } from '@playwright/test';
import { ReviewPage } from './review.page';
import { prepareTmpDirForSingleUpload, uploadFilesFromTmpDir } from '../utils/file-upload-helpers';

export class EditPage {
constructor(private page: Page) {}

async goto(organism: string, accession: string, version: number) {
await this.page.goto(`/${organism}/submission/edit/${accession}/${version}`);
}

async discardSequenceFile() {
await this.page.getByRole('button', { name: 'Discard file' }).click();
}
Expand Down Expand Up @@ -31,4 +36,14 @@ export class EditPage {
await this.page.waitForURL('**/review', { timeout: 15_000 });
return new ReviewPage(this.page);
}

async uploadExternalFiles(
fileId: string,
fileContents: Record<string, string>,
tmpDir: string,
) {
await prepareTmpDirForSingleUpload(fileContents, tmpDir);
const fileCount = Object.keys(fileContents).length;
await uploadFilesFromTmpDir(this.page, fileId, tmpDir, fileCount);
}
}
4 changes: 0 additions & 4 deletions integration-tests/tests/pages/group.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,6 @@ export class GroupPage {
await this.page.getByLabel('Address Line 1').fill(line1);
}

async editAddressLine2(line2: string) {
await this.page.getByLabel('Address Line 2').fill(line2);
}

async editCity(city: string) {
await this.page.getByLabel('City').fill(city);
}
Expand Down
8 changes: 0 additions & 8 deletions integration-tests/tests/pages/review.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,6 @@ export class ReviewPage {
.toBe(true);
}

async navigateToReviewPage() {
await this.page.goto('/');
await this.navigation.openOrganismNavigation();
await this.navigation.selectOrganism('Ebola Sudan');
await this.navigation.clickSubmitSequences();
await this.page.getByRole('link', { name: "Review Review your group's" }).click();
}

async releaseValidSequences() {
await this.page.getByRole('button', { name: /Release \d+ valid sequence/ }).click();
await this.page.getByRole('button', { name: 'Release', exact: true }).click();
Expand Down
132 changes: 12 additions & 120 deletions integration-tests/tests/pages/revision.page.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { expect, type Page } from '@playwright/test';
import { prepareTmpDirForBulkUpload, uploadFilesFromTmpDir } from '../utils/file-upload-helpers';

/**
* Page object for the sequence revision page.
Expand All @@ -14,23 +15,6 @@ export class RevisionPage {
await this.page.goto(`/${organism}/submission/${groupId}/revise`);
}

/**
* Navigate to revision page from a sequence details page
* Clicks the "Revise this sequence" link
*/
async clickReviseSequenceLink() {
// Sometimes clicking revise button doesn't register, so let's wait for sequence viewer to be visible first
// See #5447
await expect(this.page.getByTestId('fixed-length-text-viewer')).toBeVisible();

await this.page
.getByRole('link', { name: 'Revise this sequence' })
.click({ timeout: 15000 });
await expect(
this.page.getByRole('heading', { name: 'Create new revision from' }),
).toBeVisible();
}

/**
* Upload a sequence file
*/
Expand All @@ -55,39 +39,6 @@ export class RevisionPage {
await expect(this.page.getByTestId('discard_metadata_file')).toBeEnabled();
}

/**
* Upload a segment file for multi-segment organisms
*/
async uploadSegmentFile(segmentName: string, fileName: string, content: string | Buffer) {
await this.page.getByTestId(`${segmentName}_segment_file`).setInputFiles({
name: fileName,
mimeType: 'text/plain',
buffer: typeof content === 'string' ? Buffer.from(content) : content,
});
await expect(this.page.getByTestId(`discard_${segmentName}_segment_file`)).toBeEnabled();
}

/**
* Discard a segment file for multi-segment organisms
*/
async discardSegmentFile(segmentName: string) {
await this.page.getByTestId(`discard_${segmentName}_segment_file`).click();
}

/**
* Discard the sequence file
*/
async discardSequenceFile() {
await this.page.getByTestId('discard_sequence_file').click();
}

/**
* Discard the metadata file
*/
async discardMetadataFile() {
await this.page.getByTestId('discard_metadata_file').click();
}

/**
* Accept the data submission terms
*/
Expand All @@ -107,84 +58,25 @@ export class RevisionPage {
await this.page.getByRole('button', { name: 'Submit' }).click();
}

/**
* Click the Confirm button in the confirmation dialog
*/
async clickConfirm() {
await this.page.getByRole('button', { name: 'Confirm' }).click();
}

/**
* Complete the full revision submission flow
* Accepts terms, submits, and confirms
*/
async submitRevision() {
await this.acceptTerms();
await this.clickSubmit();
await this.clickConfirm();
}

/**
* Download metadata template in TSV format
*/
async downloadTsvTemplate() {
const downloadPromise = this.page.waitForEvent('download');
await this.page.getByText('TSV', { exact: true }).click();
return downloadPromise;
}

/**
* Download metadata template in XLSX format
*/
async downloadXlsxTemplate() {
const downloadPromise = this.page.waitForEvent('download');
await this.page.getByText('XLSX', { exact: true }).click();
return downloadPromise;
}

/**
* High-level helper: Revise a single-segment sequence
*/
async reviseSequence(options: {
sequenceFile?: { name: string; content: string | Buffer };
metadataFile?: { name: string; content: string | Buffer };
}) {
if (options.sequenceFile) {
await this.uploadSequenceFile(options.sequenceFile.name, options.sequenceFile.content);
}
if (options.metadataFile) {
await this.uploadMetadataFile(options.metadataFile.name, options.metadataFile.content);
}
await this.submitRevision();
}

/**
* High-level helper: Revise a multi-segment sequence
*/
async reviseMultiSegmentSequence(options: {
segments?: Record<string, { name: string; content: string | Buffer }>;
metadataFile?: { name: string; content: string | Buffer };
discardSegments?: string[];
}) {
// Discard segments first if specified
if (options.discardSegments) {
for (const segment of options.discardSegments) {
await this.discardSegmentFile(segment);
}
}

// Upload new segment files
if (options.segments) {
for (const [segmentName, file] of Object.entries(options.segments)) {
await this.uploadSegmentFile(segmentName, file.name, file.content);
}
}

// Upload metadata if provided
if (options.metadataFile) {
await this.uploadMetadataFile(options.metadataFile.name, options.metadataFile.content);
}

await this.submitRevision();
async uploadExternalFiles(
fileId: string,
fileContents: Record<string, Record<string, string>>,
tmpDir: string,
) {
await prepareTmpDirForBulkUpload(fileContents, tmpDir);
const fileCount = Object.values(fileContents).reduce(
(total, files) => total + Object.keys(files).length,
0,
);
await uploadFilesFromTmpDir(this.page, fileId, tmpDir, fileCount);
}
}
8 changes: 0 additions & 8 deletions integration-tests/tests/pages/search.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,6 @@ export class SearchPage {
return accessionVersion;
}

getSequencePreviewModal() {
return this.page.locator('[data-testid="sequence-preview-modal"]');
}

getHalfScreenPreview() {
return this.page.locator('[data-testid="half-screen-preview"]');
}

toggleHalfScreenButton() {
return this.page.locator('[data-testid="toggle-half-screen-button"]');
}
Expand Down
10 changes: 0 additions & 10 deletions integration-tests/tests/pages/sequence-detail.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,6 @@ export class SequenceDetailPage {
}
}

async selectAlignedTab() {
if (await this.alignedTab.isVisible()) {
await this.alignedTab.click();
}
}

async expectSequenceContentVisible(timeout = 10000) {
await expect(this.page.getByText(/[ACGTN]{20,}/)).toBeVisible({ timeout });
}
Expand Down Expand Up @@ -83,8 +77,4 @@ export class SequenceDetailPage {
await expect(link).toBeVisible();
await link.click();
}

getPage() {
return this.page;
}
}
Loading
Loading