n8n/packages/testing/playwright/pages/SourceControlPushModal.ts
Declan Carroll f96cdb17db
Some checks are pending
CI: Master (Build, Test, Lint) / Build for Github Cache (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (22.x) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (24.14.1) (push) Waiting to run
CI: Master (Build, Test, Lint) / Unit tests (25.x) (push) Waiting to run
CI: Master (Build, Test, Lint) / Lint (push) Waiting to run
CI: Master (Build, Test, Lint) / Performance (push) Waiting to run
CI: Master (Build, Test, Lint) / Notify Slack on failure (push) Blocked by required conditions
test: Resolve 20 janitor scope-lockdown and dead-code violations (#27948)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 17:32:27 +00:00

94 lines
2.6 KiB
TypeScript

import type { GitCommitInfo, SourceControlledFile } from '@n8n/api-types';
import type { Locator, Page } from '@playwright/test';
export interface PushResult {
files: SourceControlledFile[];
commit: GitCommitInfo | null;
}
export class SourceControlPushModal {
constructor(private readonly page: Page) {}
get container() {
return this.page.getByTestId('sourceControlPush-modal');
}
getSubmitButton(): Locator {
return this.container.getByTestId('source-control-push-modal-submit');
}
async push(commitMessage: string): Promise<PushResult> {
await this.container.getByTestId('source-control-push-modal-commit').fill(commitMessage);
const responsePromise = this.page.waitForResponse(
(response) =>
response.url().includes('/rest/source-control/push-workfolder') &&
response.status() === 200,
);
await this.getSubmitButton().click();
const response = await responsePromise;
const json = await response.json();
return json.data as PushResult;
}
// Tabs
getWorkflowsTab(): Locator {
return this.container.getByTestId('source-control-push-modal-tab-workflow');
}
getCredentialsTab(): Locator {
return this.container.getByTestId('source-control-push-modal-tab-credential');
}
async selectWorkflowsTab(): Promise<void> {
await this.getWorkflowsTab().click();
}
async selectCredentialsTab(): Promise<void> {
await this.getCredentialsTab().click();
}
isWorkflowsTabSelected(): Promise<boolean> {
return this.getWorkflowsTab()
.getAttribute('class')
.then((classList) => classList?.includes('tabActive') ?? false);
}
// File items
getFileInModal(fileName: string): Locator {
return this.container.getByTestId('push-modal-item').filter({ hasText: fileName }).first();
}
getFileCheckboxByName(fileName: string): Locator {
return this.container
.locator('[data-test-id="source-control-push-modal-file-checkbox"]')
.filter({ has: this.container.getByText(fileName, { exact: true }) });
}
async selectAllFilesInModal(): Promise<void> {
const toggleAll = this.container.getByTestId('source-control-push-modal-toggle-all');
const isChecked = await toggleAll.isChecked();
if (!isChecked) {
await toggleAll.click();
}
}
getNotice(): Locator {
return this.container.locator('#source-control-push-modal-notice.notice[role="alert"]');
}
getStatusBadge(fileName: string, status: 'New' | 'Modified' | 'Deleted'): Locator {
return this.getFileCheckboxByName(fileName).getByText(status);
}
async selectFile(fileName: string): Promise<void> {
const checkbox = this.getFileCheckboxByName(fileName);
const isChecked = await checkbox.isChecked();
if (!isChecked) {
await checkbox.click();
}
}
}