mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-27 23:07:12 +02:00
236 lines
6.8 KiB
TypeScript
236 lines
6.8 KiB
TypeScript
import type { Locator } from '@playwright/test';
|
|
|
|
import { BasePage } from './BasePage';
|
|
|
|
export class SettingsLogStreamingPage extends BasePage {
|
|
async goto(): Promise<void> {
|
|
await this.page.goto('/settings/log-streaming');
|
|
}
|
|
|
|
getActionBoxUnlicensed(): Locator {
|
|
return this.page.getByTestId('action-box-unlicensed');
|
|
}
|
|
|
|
getActionBoxLicensed(): Locator {
|
|
return this.page.getByTestId('action-box-licensed');
|
|
}
|
|
|
|
getContactUsButton(): Locator {
|
|
return this.getActionBoxUnlicensed().locator('button');
|
|
}
|
|
|
|
getAddFirstDestinationButton(): Locator {
|
|
return this.getActionBoxLicensed().locator('button');
|
|
}
|
|
|
|
getAddNewDestinationButton(): Locator {
|
|
return this.page.getByRole('button', { name: 'Add new destination' });
|
|
}
|
|
|
|
getDestinationModal(): Locator {
|
|
return this.page.getByTestId('destination-modal');
|
|
}
|
|
|
|
getSelectDestinationType(): Locator {
|
|
return this.page.getByTestId('select-destination-type');
|
|
}
|
|
|
|
getSelectDestinationTypeItems(): Locator {
|
|
return this.page.locator('.el-select-dropdown__item');
|
|
}
|
|
|
|
getSelectDestinationButton(): Locator {
|
|
return this.page.getByTestId('select-destination-button');
|
|
}
|
|
|
|
getDestinationNameInput(): Locator {
|
|
return this.page.getByTestId('subtitle-showing-type');
|
|
}
|
|
|
|
getDestinationSaveButton(): Locator {
|
|
return this.page.getByTestId('destination-save-button').locator('button');
|
|
}
|
|
|
|
getDestinationDeleteButton(): Locator {
|
|
return this.page.getByTestId('destination-delete-button');
|
|
}
|
|
|
|
getDestinationCards(): Locator {
|
|
return this.page.getByTestId('destination-card');
|
|
}
|
|
|
|
getDropdownMenuItem(index: number): Locator {
|
|
return this.page
|
|
.getByTestId('action-toggle-dropdown')
|
|
.filter({ visible: true })
|
|
.getByRole('menuitem')
|
|
.nth(index);
|
|
}
|
|
|
|
getConfirmationDialog(): Locator {
|
|
return this.page.locator('.el-message-box');
|
|
}
|
|
|
|
getCancelButton(): Locator {
|
|
return this.page.locator('.btn--cancel');
|
|
}
|
|
|
|
getConfirmButton(): Locator {
|
|
return this.page.locator('.btn--confirm');
|
|
}
|
|
|
|
async addDestination(): Promise<void> {
|
|
const addFirstButton = this.getAddFirstDestinationButton();
|
|
const addNewButton = this.getAddNewDestinationButton();
|
|
await addFirstButton.or(addNewButton).click();
|
|
}
|
|
|
|
async clickSelectDestinationType(): Promise<void> {
|
|
await this.clickByTestId('select-destination-type');
|
|
}
|
|
|
|
async selectDestinationType(index: number): Promise<void> {
|
|
await this.getSelectDestinationTypeItems().nth(index).click();
|
|
}
|
|
|
|
async clickSelectDestinationButton(): Promise<void> {
|
|
await this.clickByTestId('select-destination-button');
|
|
}
|
|
|
|
async clickDestinationNameInput(): Promise<void> {
|
|
await this.clickByTestId('subtitle-showing-type');
|
|
}
|
|
|
|
async writeUrlToDestinationUrlInput(url: string): Promise<void> {
|
|
await this.page.getByTestId('parameter-input-field').fill(url);
|
|
}
|
|
|
|
async clickInlineEditPreview(): Promise<void> {
|
|
// First click on the destination name input to activate it
|
|
await this.getDestinationNameInput().click();
|
|
const inlineEditPreview = this.getDestinationNameInput().locator(
|
|
'span[data-test-id="inline-edit-preview"]',
|
|
);
|
|
// eslint-disable-next-line playwright/no-force-option
|
|
await inlineEditPreview.click({ force: true });
|
|
}
|
|
|
|
async typeDestinationName(name: string): Promise<void> {
|
|
await this.fillByTestId('inline-edit-input', name);
|
|
}
|
|
|
|
async saveDestination(): Promise<void> {
|
|
const responsePromise = this.page.waitForResponse(
|
|
(res) => res.url().includes('/eventbus/destination') && res.request().method() === 'POST',
|
|
);
|
|
await this.getDestinationSaveButton().click();
|
|
await responsePromise;
|
|
}
|
|
|
|
async deleteDestination(): Promise<void> {
|
|
await this.clickByTestId('destination-delete-button');
|
|
}
|
|
|
|
async clickDestinationCard(index: number): Promise<void> {
|
|
await this.getDestinationCards().nth(index).click();
|
|
}
|
|
|
|
async clickDestinationCardDropdown(index: number): Promise<void> {
|
|
await this.getDestinationCards()
|
|
.nth(index)
|
|
.getByTestId('action-toggle')
|
|
.getByRole('button')
|
|
.click();
|
|
}
|
|
|
|
async clickDropdownMenuItem(index: number): Promise<void> {
|
|
await this.getDropdownMenuItem(index).click();
|
|
}
|
|
|
|
async closeModalByClickingOverlay(): Promise<void> {
|
|
await this.page
|
|
.locator('.el-overlay')
|
|
.filter({ has: this.getDestinationModal() })
|
|
.click({ position: { x: 1, y: 1 } });
|
|
}
|
|
|
|
async confirmDialog(): Promise<void> {
|
|
await this.getConfirmButton().click();
|
|
}
|
|
|
|
async cancelDialog(): Promise<void> {
|
|
await this.getCancelButton().click();
|
|
}
|
|
|
|
/**
|
|
* Creates a new webhook log streaming destination with the specified name.
|
|
* Handles the full flow: modal opening, type selection, naming, and saving.
|
|
* @param destinationName - The name to give the new destination
|
|
*/
|
|
async createDestination(destinationName: string): Promise<void> {
|
|
await this.addDestination();
|
|
await this.getDestinationModal().waitFor({ state: 'visible' });
|
|
await this.clickSelectDestinationType();
|
|
await this.selectDestinationType(0); // Webhook
|
|
await this.clickSelectDestinationButton();
|
|
await this.clickDestinationNameInput();
|
|
await this.clickInlineEditPreview();
|
|
await this.typeDestinationName(destinationName);
|
|
await this.writeUrlToDestinationUrlInput('https://www.example.com');
|
|
await this.saveDestination();
|
|
await this.closeModalByClickingOverlay();
|
|
}
|
|
|
|
/**
|
|
* Creates a new syslog log streaming destination.
|
|
* @param config - Syslog configuration
|
|
*/
|
|
async createSyslogDestination(config: {
|
|
name: string;
|
|
host: string;
|
|
port: number;
|
|
}): Promise<void> {
|
|
await this.addDestination();
|
|
await this.getDestinationModal().waitFor({ state: 'visible' });
|
|
await this.clickSelectDestinationType();
|
|
await this.selectDestinationType(2); // Syslog (0=Webhook, 1=Sentry, 2=Syslog)
|
|
await this.clickSelectDestinationButton();
|
|
|
|
// Set destination name
|
|
await this.clickDestinationNameInput();
|
|
await this.clickInlineEditPreview();
|
|
await this.typeDestinationName(config.name);
|
|
|
|
// Fill syslog config - host and port fields
|
|
const hostInput = this.page.getByTestId('parameter-input-host').locator('input');
|
|
const portInput = this.page.getByTestId('parameter-input-port').locator('input');
|
|
|
|
await hostInput.clear();
|
|
await hostInput.fill(config.host);
|
|
await this.page.waitForTimeout(300);
|
|
await portInput.clear();
|
|
await portInput.fill(config.port.toString());
|
|
|
|
// Wait for debounced input update (200ms debounce in ParameterInput.vue)
|
|
await this.page.waitForTimeout(200);
|
|
await this.saveDestination();
|
|
}
|
|
|
|
/**
|
|
* Gets the send test event button
|
|
*/
|
|
getSendTestEventButton(): Locator {
|
|
return this.page.getByTestId('destination-test-button');
|
|
}
|
|
|
|
/**
|
|
* Sends a test event to the destination.
|
|
* Must be called while the destination modal is open and the destination has been saved.
|
|
*/
|
|
async sendTestEvent(): Promise<void> {
|
|
const testButton = this.getSendTestEventButton();
|
|
await testButton.waitFor({ state: 'visible' });
|
|
await testButton.click();
|
|
}
|
|
}
|