Update playwright (#10927)
Update twenty-e2e-testing to reflect actual state of app
This commit is contained in:
@ -3,18 +3,4 @@ FRONTEND_BASE_URL=http://localhost:3001
|
||||
BACKEND_BASE_URL=http://localhost:3000
|
||||
DEFAULT_LOGIN=tim@apple.dev
|
||||
DEFAULT_PASSWORD=Applecar2025
|
||||
WEBSITE_URL=https://twenty.com
|
||||
|
||||
# === DO NOT USE, WORK IN PROGRESS ===
|
||||
# This URL must have trailing forward slash as all REST API endpoints have object after it
|
||||
# Documentation for REST API: https://twenty.com/developers/rest-api/core#/
|
||||
# REST_API_BASE_URL=http://localhost:3000/rest/
|
||||
|
||||
# Documentation for GraphQL API: https://twenty.com/developers/graphql/core
|
||||
# GRAPHQL_BASE_URL=http://localhost:3000/graphql
|
||||
|
||||
# Without this key, all API tests will fail, to generate this key
|
||||
# Log in to Twenty workspace, go to Settings > Developers, generate new key and paste it here
|
||||
# In order to use it, header Authorization: Bearer token must be used
|
||||
# This key works for both REST and GraphQL API
|
||||
# API_DEV_KEY=fill_with_proper_key
|
||||
WEBSITE_URL=https://twenty.com
|
||||
@ -25,7 +25,7 @@ export const test = base.extend<{ screenshotHook: void }>({
|
||||
),
|
||||
});
|
||||
},
|
||||
{ auto: true }, // automatic fixture runs with every test
|
||||
{ auto: true },
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ export class InsertFieldData {
|
||||
'//label[contains(., "POST CODE")]/../div[last()]/input',
|
||||
);
|
||||
this.countrySelect = page.locator(
|
||||
'//span[contains(., "COUNTRY")]/../div[last()]/input',
|
||||
'//span[contains(., "COUNTRY")]/../div[last()]/div',
|
||||
);
|
||||
this.arrayValueInput = page.locator("//input[@placeholder='Enter value']");
|
||||
this.arrayAddValueButton = page.locator(
|
||||
|
||||
@ -1,5 +1,55 @@
|
||||
import { Locator, Page } from '@playwright/test';
|
||||
|
||||
export class StripePage {
|
||||
// TODO: implement all necessary methods (staging/sandbox page - does it differ anyhow from normal page?)
|
||||
private readonly cardNumberInput: Locator;
|
||||
private readonly cardExpiryInput: Locator;
|
||||
private readonly cardCvcInput: Locator;
|
||||
private readonly cardholderNameInput: Locator;
|
||||
private readonly startTrialButton: Locator;
|
||||
private readonly cancelSubscriptionButton: Locator;
|
||||
private readonly confirmButton: Locator;
|
||||
private readonly returnToTwentyLink: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.cardNumberInput = page.getByPlaceholder('1234 1234 1234 1234');
|
||||
this.cardExpiryInput = page.getByPlaceholder('MM / YY');
|
||||
this.cardCvcInput = page.getByPlaceholder('CVC');
|
||||
this.cardholderNameInput = page.getByPlaceholder('Full name on card');
|
||||
this.startTrialButton = page.getByTestId('hosted-payment-submit-button');
|
||||
this.cancelSubscriptionButton = page.locator(
|
||||
'a[data-test="cancel-subscription"]',
|
||||
);
|
||||
this.confirmButton = page.getByTestId('confirm');
|
||||
this.returnToTwentyLink = page.getByTestId('return-to-business-link');
|
||||
}
|
||||
|
||||
async fillCardNumber(number: string) {
|
||||
await this.cardNumberInput.fill(number);
|
||||
}
|
||||
|
||||
async fillCardExpiry(expiry: string) {
|
||||
await this.cardExpiryInput.fill(expiry);
|
||||
}
|
||||
|
||||
async fillCardCvc(cvc: string) {
|
||||
await this.cardCvcInput.fill(cvc);
|
||||
}
|
||||
|
||||
async fillCardholderName(name: string) {
|
||||
await this.cardholderNameInput.fill(name);
|
||||
}
|
||||
|
||||
async startTrial() {
|
||||
await this.startTrialButton.click();
|
||||
}
|
||||
|
||||
async clickCancelSubscription() {
|
||||
await this.cancelSubscriptionButton.click();
|
||||
await this.confirmButton.click();
|
||||
await this.page.getByTestId('cancellation_reason_cancel').click();
|
||||
}
|
||||
|
||||
async returnToTwenty() {
|
||||
await this.returnToTwentyLink.click();
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ export class AccountsSection {
|
||||
private readonly addBlocklistField: Locator;
|
||||
private readonly addBlocklistButton: Locator;
|
||||
private readonly connectWithGoogleButton: Locator;
|
||||
private readonly connectWithMicrosoftButton: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.page = page;
|
||||
@ -22,6 +23,9 @@ export class AccountsSection {
|
||||
this.connectWithGoogleButton = page.getByRole('button', {
|
||||
name: 'Connect with Google',
|
||||
});
|
||||
this.connectWithMicrosoftButton = page.getByRole('button', {
|
||||
name: 'Connect with Microsoft',
|
||||
});
|
||||
}
|
||||
|
||||
async clickAddAccount() {
|
||||
@ -51,4 +55,8 @@ export class AccountsSection {
|
||||
async linkGoogleAccount() {
|
||||
await this.connectWithGoogleButton.click();
|
||||
}
|
||||
|
||||
async linkMicrosoftAccount() {
|
||||
await this.connectWithMicrosoftButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
64
packages/twenty-e2e-testing/lib/pom/settings/apisSection.ts
Normal file
64
packages/twenty-e2e-testing/lib/pom/settings/apisSection.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { Locator, Page } from '@playwright/test';
|
||||
|
||||
export class APIsSection {
|
||||
private readonly createAPIKeyButton: Locator;
|
||||
private readonly regenerateAPIKeyButton: Locator;
|
||||
private readonly nameOfAPIKeyInput: Locator;
|
||||
private readonly expirationDateAPIKeySelect: Locator;
|
||||
private readonly cancelButton: Locator;
|
||||
private readonly saveButton: Locator;
|
||||
private readonly deleteButton: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.page = page;
|
||||
this.createAPIKeyButton = page.getByRole('link', {
|
||||
name: 'Create API Key',
|
||||
});
|
||||
this.nameOfAPIKeyInput = page
|
||||
.getByPlaceholder('E.g. backoffice integration')
|
||||
.first();
|
||||
this.expirationDateAPIKeySelect = page.locator(
|
||||
'div[aria-controls="object-field-type-select-options"]',
|
||||
);
|
||||
this.regenerateAPIKeyButton = page.getByRole('button', {
|
||||
name: 'Regenerate Key',
|
||||
});
|
||||
this.cancelButton = page.getByRole('button', { name: 'Cancel' });
|
||||
this.saveButton = page.getByRole('button', { name: 'Save' });
|
||||
this.deleteButton = page.getByRole('button', { name: 'Delete' });
|
||||
}
|
||||
|
||||
async createAPIKey() {
|
||||
await this.createAPIKeyButton.click();
|
||||
}
|
||||
|
||||
async typeAPIKeyName(name: string) {
|
||||
await this.nameOfAPIKeyInput.clear();
|
||||
await this.nameOfAPIKeyInput.fill(name);
|
||||
}
|
||||
|
||||
async selectAPIExpirationDate(date: string) {
|
||||
await this.expirationDateAPIKeySelect.click();
|
||||
await this.page.getByText(date, { exact: true }).click();
|
||||
}
|
||||
|
||||
async regenerateAPIKey() {
|
||||
await this.regenerateAPIKeyButton.click();
|
||||
}
|
||||
|
||||
async deleteAPIKey() {
|
||||
await this.deleteButton.click();
|
||||
}
|
||||
|
||||
async clickCancelButton() {
|
||||
await this.cancelButton.click();
|
||||
}
|
||||
|
||||
async clickSaveButton() {
|
||||
await this.saveButton.click();
|
||||
}
|
||||
|
||||
async checkAPIKeyDetails(name: string) {
|
||||
await this.page.locator(`//a/div[contains(.,'${name}')][first()]`).click();
|
||||
}
|
||||
}
|
||||
@ -1,123 +0,0 @@
|
||||
import { Locator, Page } from '@playwright/test';
|
||||
|
||||
export class DevelopersSection {
|
||||
private readonly readDocumentationButton: Locator;
|
||||
private readonly createAPIKeyButton: Locator;
|
||||
private readonly regenerateAPIKeyButton: Locator;
|
||||
private readonly nameOfAPIKeyInput: Locator;
|
||||
private readonly expirationDateAPIKeySelect: Locator;
|
||||
private readonly createWebhookButton: Locator;
|
||||
private readonly webhookURLInput: Locator;
|
||||
private readonly webhookDescription: Locator;
|
||||
private readonly webhookFilterObjectSelect: Locator;
|
||||
private readonly webhookFilterActionSelect: Locator;
|
||||
private readonly cancelButton: Locator;
|
||||
private readonly saveButton: Locator;
|
||||
private readonly deleteButton: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.page = page;
|
||||
this.readDocumentationButton = page.getByRole('link', {
|
||||
name: 'Read documentation',
|
||||
});
|
||||
this.createAPIKeyButton = page.getByRole('link', {
|
||||
name: 'Create API Key',
|
||||
});
|
||||
this.createWebhookButton = page.getByRole('link', {
|
||||
name: 'Create Webhook',
|
||||
});
|
||||
this.nameOfAPIKeyInput = page
|
||||
.getByPlaceholder('E.g. backoffice integration')
|
||||
.first();
|
||||
this.expirationDateAPIKeySelect = page
|
||||
.locator('div')
|
||||
.filter({ hasText: /^Never$/ })
|
||||
.nth(3); // good enough if expiration date will change only 1 time
|
||||
this.regenerateAPIKeyButton = page.getByRole('button', {
|
||||
name: 'Regenerate Key',
|
||||
});
|
||||
this.webhookURLInput = page.getByPlaceholder('URL');
|
||||
this.webhookDescription = page.getByPlaceholder('Write a description');
|
||||
this.webhookFilterObjectSelect = page
|
||||
.locator('div')
|
||||
.filter({ hasText: /^All Objects$/ })
|
||||
.nth(3); // works only for first filter
|
||||
this.webhookFilterActionSelect = page
|
||||
.locator('div')
|
||||
.filter({ hasText: /^All Actions$/ })
|
||||
.nth(3); // works only for first filter
|
||||
this.cancelButton = page.getByRole('button', { name: 'Cancel' });
|
||||
this.saveButton = page.getByRole('button', { name: 'Save' });
|
||||
this.deleteButton = page.getByRole('button', { name: 'Delete' });
|
||||
}
|
||||
|
||||
async openDocumentation() {
|
||||
await this.readDocumentationButton.click();
|
||||
}
|
||||
|
||||
async createAPIKey() {
|
||||
await this.createAPIKeyButton.click();
|
||||
}
|
||||
|
||||
async typeAPIKeyName(name: string) {
|
||||
await this.nameOfAPIKeyInput.clear();
|
||||
await this.nameOfAPIKeyInput.fill(name);
|
||||
}
|
||||
|
||||
async selectAPIExpirationDate(date: string) {
|
||||
await this.expirationDateAPIKeySelect.click();
|
||||
await this.page.getByText(date, { exact: true }).click();
|
||||
}
|
||||
|
||||
async regenerateAPIKey() {
|
||||
await this.regenerateAPIKeyButton.click();
|
||||
}
|
||||
|
||||
async deleteAPIKey() {
|
||||
await this.deleteButton.click();
|
||||
}
|
||||
|
||||
async deleteWebhook() {
|
||||
await this.deleteButton.click();
|
||||
}
|
||||
|
||||
async createWebhook() {
|
||||
await this.createWebhookButton.click();
|
||||
}
|
||||
|
||||
async typeWebhookURL(url: string) {
|
||||
await this.webhookURLInput.fill(url);
|
||||
}
|
||||
|
||||
async typeWebhookDescription(description: string) {
|
||||
await this.webhookDescription.fill(description);
|
||||
}
|
||||
|
||||
async selectWebhookObject(object: string) {
|
||||
// TODO: finish
|
||||
}
|
||||
|
||||
async selectWebhookAction(action: string) {
|
||||
// TODO: finish
|
||||
}
|
||||
|
||||
async deleteWebhookFilter() {
|
||||
// TODO: finish
|
||||
}
|
||||
|
||||
async clickCancelButton() {
|
||||
await this.cancelButton.click();
|
||||
}
|
||||
|
||||
async clickSaveButton() {
|
||||
await this.saveButton.click();
|
||||
}
|
||||
|
||||
async checkAPIKeyDetails(name: string) {
|
||||
await this.page.locator(`//a/div[contains(.,'${name}')][first()]`).click();
|
||||
}
|
||||
|
||||
async checkWebhookDetails(name: string) {
|
||||
await this.page.locator(`//a/div[contains(.,'${name}')][first()]`).click();
|
||||
}
|
||||
}
|
||||
@ -7,11 +7,12 @@ export class ExperienceSection {
|
||||
private readonly dateFormatDropdown: Locator;
|
||||
private readonly timeFormatDropdown: Locator;
|
||||
private readonly searchInput: Locator;
|
||||
private readonly languageDropdown: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.page = page;
|
||||
this.lightThemeButton = page.getByText('AaLight'); // it works
|
||||
this.darkThemeButton = page.getByText('AaDark');
|
||||
this.lightThemeButton = page.locator('div[variant="Light"]').first();
|
||||
this.darkThemeButton = page.locator('div[variant="Dark"]').first();
|
||||
this.timezoneDropdown = page.locator(
|
||||
'//span[contains(., "Time zone")]/../div/div/div',
|
||||
);
|
||||
@ -22,6 +23,9 @@ export class ExperienceSection {
|
||||
'//span[contains(., "Time format")]/../div/div/div',
|
||||
);
|
||||
this.searchInput = page.getByPlaceholder('Search');
|
||||
this.languageDropdown = page.locator(
|
||||
'//h2[contains(., "Language")]/../../../div/div/div',
|
||||
);
|
||||
}
|
||||
|
||||
async changeThemeToLight() {
|
||||
@ -52,4 +56,9 @@ export class ExperienceSection {
|
||||
await this.timeFormatDropdown.click();
|
||||
await this.page.getByText(timeFormat, { exact: true }).click();
|
||||
}
|
||||
|
||||
async selectLanguage(language: string) {
|
||||
await this.languageDropdown.click();
|
||||
await this.page.getByText(language, { exact: true }).click();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,159 +0,0 @@
|
||||
import { Locator, Page } from '@playwright/test';
|
||||
|
||||
export class FunctionsSection {
|
||||
private readonly newFunctionButton: Locator;
|
||||
private readonly functionNameInput: Locator;
|
||||
private readonly functionDescriptionInput: Locator;
|
||||
private readonly editorTab: Locator;
|
||||
private readonly codeEditorField: Locator;
|
||||
private readonly resetButton: Locator;
|
||||
private readonly publishButton: Locator;
|
||||
private readonly testButton: Locator;
|
||||
private readonly testTab: Locator;
|
||||
private readonly runFunctionButton: Locator;
|
||||
private readonly inputField: Locator;
|
||||
private readonly settingsTab: Locator;
|
||||
private readonly searchVariableInput: Locator;
|
||||
private readonly addVariableButton: Locator;
|
||||
private readonly nameVariableInput: Locator;
|
||||
private readonly valueVariableInput: Locator;
|
||||
private readonly cancelVariableButton: Locator;
|
||||
private readonly saveVariableButton: Locator;
|
||||
private readonly editVariableButton: Locator;
|
||||
private readonly deleteVariableButton: Locator;
|
||||
private readonly cancelButton: Locator;
|
||||
private readonly saveButton: Locator;
|
||||
private readonly deleteButton: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.newFunctionButton = page.getByRole('button', { name: 'New Function' });
|
||||
this.functionNameInput = page.getByPlaceholder('Name');
|
||||
this.functionDescriptionInput = page.getByPlaceholder('Description');
|
||||
this.editorTab = page.getByTestId('tab-editor');
|
||||
this.codeEditorField = page.getByTestId('dummyInput'); // TODO: fix
|
||||
this.resetButton = page.getByRole('button', { name: 'Reset' });
|
||||
this.publishButton = page.getByRole('button', { name: 'Publish' });
|
||||
this.testButton = page.getByRole('button', { name: 'Test' });
|
||||
this.testTab = page.getByTestId('tab-test');
|
||||
this.runFunctionButton = page.getByRole('button', { name: 'Run Function' });
|
||||
this.inputField = page.getByTestId('dummyInput'); // TODO: fix
|
||||
this.settingsTab = page.getByTestId('tab-settings');
|
||||
this.searchVariableInput = page.getByPlaceholder('Search a variable');
|
||||
this.addVariableButton = page.getByRole('button', { name: 'Add Variable' });
|
||||
this.nameVariableInput = page.getByPlaceholder('Name').nth(1);
|
||||
this.valueVariableInput = page.getByPlaceholder('Value');
|
||||
this.cancelVariableButton = page.locator('.css-uwqduk').first(); // TODO: fix
|
||||
this.saveVariableButton = page.locator('.css-uwqduk').nth(1); // TODO: fix
|
||||
this.editVariableButton = page.getByText('Edit', { exact: true });
|
||||
this.deleteVariableButton = page.getByText('Delete', { exact: true });
|
||||
this.cancelButton = page.getByRole('button', { name: 'Cancel' });
|
||||
this.saveButton = page.getByRole('button', { name: 'Save' });
|
||||
this.deleteButton = page.getByRole('button', { name: 'Delete function' });
|
||||
}
|
||||
|
||||
async clickNewFunction() {
|
||||
await this.newFunctionButton.click();
|
||||
}
|
||||
|
||||
async typeFunctionName(name: string) {
|
||||
await this.functionNameInput.fill(name);
|
||||
}
|
||||
|
||||
async typeFunctionDescription(description: string) {
|
||||
await this.functionDescriptionInput.fill(description);
|
||||
}
|
||||
|
||||
async checkFunctionDetails(name: string) {
|
||||
await this.page.getByRole('link', { name: `${name} nodejs18.x` }).click();
|
||||
}
|
||||
|
||||
async clickEditorTab() {
|
||||
await this.editorTab.click();
|
||||
}
|
||||
|
||||
async clickResetButton() {
|
||||
await this.resetButton.click();
|
||||
}
|
||||
|
||||
async clickPublishButton() {
|
||||
await this.publishButton.click();
|
||||
}
|
||||
|
||||
async clickTestButton() {
|
||||
await this.testButton.click();
|
||||
}
|
||||
|
||||
async typeFunctionCode() {
|
||||
// TODO: finish once utils are merged
|
||||
}
|
||||
|
||||
async clickTestTab() {
|
||||
await this.testTab.click();
|
||||
}
|
||||
|
||||
async runFunction() {
|
||||
await this.runFunctionButton.click();
|
||||
}
|
||||
|
||||
async typeFunctionInput() {
|
||||
// TODO: finish once utils are merged
|
||||
}
|
||||
|
||||
async clickSettingsTab() {
|
||||
await this.settingsTab.click();
|
||||
}
|
||||
|
||||
async searchVariable(name: string) {
|
||||
await this.searchVariableInput.fill(name);
|
||||
}
|
||||
|
||||
async addVariable() {
|
||||
await this.addVariableButton.click();
|
||||
}
|
||||
|
||||
async typeVariableName(name: string) {
|
||||
await this.nameVariableInput.fill(name);
|
||||
}
|
||||
|
||||
async typeVariableValue(value: string) {
|
||||
await this.valueVariableInput.fill(value);
|
||||
}
|
||||
|
||||
async editVariable(name: string) {
|
||||
await this.page
|
||||
.locator(
|
||||
`//div[@data-testid='tooltip' and contains(., '${name}')]/../../div[last()]/div/div/button`,
|
||||
)
|
||||
.click();
|
||||
await this.editVariableButton.click();
|
||||
}
|
||||
|
||||
async deleteVariable(name: string) {
|
||||
await this.page
|
||||
.locator(
|
||||
`//div[@data-testid='tooltip' and contains(., '${name}')]/../../div[last()]/div/div/button`,
|
||||
)
|
||||
.click();
|
||||
await this.deleteVariableButton.click();
|
||||
}
|
||||
|
||||
async cancelVariable() {
|
||||
await this.cancelVariableButton.click();
|
||||
}
|
||||
|
||||
async saveVariable() {
|
||||
await this.saveVariableButton.click();
|
||||
}
|
||||
|
||||
async clickCancelButton() {
|
||||
await this.cancelButton.click();
|
||||
}
|
||||
|
||||
async clickSaveButton() {
|
||||
await this.saveButton.click();
|
||||
}
|
||||
|
||||
async clickDeleteButton() {
|
||||
await this.deleteButton.click();
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,8 @@ export class GeneralSection {
|
||||
private readonly workspaceNameField: Locator;
|
||||
private readonly supportSwitch: Locator;
|
||||
private readonly deleteWorkspaceButton: Locator;
|
||||
private readonly customizeDomainButton: Locator;
|
||||
private readonly subdomainInput: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.page = page;
|
||||
@ -12,6 +14,12 @@ export class GeneralSection {
|
||||
this.deleteWorkspaceButton = page.getByRole('button', {
|
||||
name: 'Delete workspace',
|
||||
});
|
||||
this.customizeDomainButton = page.getByRole('button', {
|
||||
name: 'Customize domain',
|
||||
});
|
||||
this.subdomainInput = page.locator(
|
||||
'//div[contains(.,".twenty-main.com")]/../input',
|
||||
);
|
||||
}
|
||||
|
||||
async changeWorkspaceName(workspaceName: string) {
|
||||
@ -26,4 +34,10 @@ export class GeneralSection {
|
||||
async clickDeleteWorkSpaceButton() {
|
||||
await this.deleteWorkspaceButton.click();
|
||||
}
|
||||
|
||||
async changeSubdomain(subdomain: string) {
|
||||
await this.customizeDomainButton.click();
|
||||
await this.subdomainInput.fill(subdomain);
|
||||
await this.page.getByRole('button', { name: 'Save' }).click();
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ export class NewFieldSection {
|
||||
private readonly relationFieldLink: Locator;
|
||||
private readonly relationTypeSelect: Locator;
|
||||
private readonly objectDestinationSelect: Locator;
|
||||
private readonly relationIconSelect: Locator;
|
||||
private readonly relationFieldNameInput: Locator;
|
||||
private readonly fullNameFieldLink: Locator;
|
||||
private readonly UUIDFieldLink: Locator;
|
||||
@ -225,6 +226,11 @@ export class NewFieldSection {
|
||||
await this.page.getByTestId('tooltip').filter({ hasText: name }).click();
|
||||
}
|
||||
|
||||
async selectRelationIcon(name: string) {
|
||||
await this.relationIconSelect.click();
|
||||
await this.page.getByTitle(name).click();
|
||||
}
|
||||
|
||||
async typeRelationName(name: string) {
|
||||
await this.relationFieldNameInput.clear();
|
||||
await this.relationFieldNameInput.fill(name);
|
||||
|
||||
22
packages/twenty-e2e-testing/lib/pom/settings/rolesSection.ts
Normal file
22
packages/twenty-e2e-testing/lib/pom/settings/rolesSection.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { Locator, Page } from '@playwright/test';
|
||||
|
||||
export class RolesSection {
|
||||
private readonly page: Page;
|
||||
private readonly createRoleButton: Locator;
|
||||
private readonly defaultRoleDropdown: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.createRoleButton = page.getByRole('button', { name: 'Create Role' });
|
||||
this.defaultRoleDropdown = page.getByTestId('tooltip');
|
||||
}
|
||||
|
||||
async clickCreateRoleButton() {
|
||||
await this.createRoleButton.click();
|
||||
}
|
||||
|
||||
async selectDefaultRole(role: string) {
|
||||
await this.defaultRoleDropdown.click();
|
||||
await this.page.getByTestId('tooltip').getByText(role).click();
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,28 @@
|
||||
import { Locator, Page } from '@playwright/test';
|
||||
|
||||
export class SecuritySection {
|
||||
private readonly googleToggle: Locator;
|
||||
private readonly microsoftToggle: Locator;
|
||||
private readonly passwordToggle: Locator;
|
||||
private readonly inviteByLinkToggle: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.inviteByLinkToggle = page.locator('input[type="checkbox"]').nth(1);
|
||||
this.googleToggle = page.getByLabel('Google');
|
||||
this.microsoftToggle = page.getByLabel('Microsoft');
|
||||
this.passwordToggle = page.getByLabel('Password');
|
||||
this.inviteByLinkToggle = page.getByLabel('Invite by Link');
|
||||
}
|
||||
|
||||
async toggleGoogle() {
|
||||
await this.googleToggle.click();
|
||||
}
|
||||
|
||||
async toggleMicrosoft() {
|
||||
await this.microsoftToggle.click();
|
||||
}
|
||||
|
||||
async togglePassword() {
|
||||
await this.passwordToggle.click();
|
||||
}
|
||||
|
||||
async toggleInviteByLink() {
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
import { Locator, Page } from '@playwright/test';
|
||||
|
||||
export class WebhooksSection {
|
||||
private readonly createWebhookButton: Locator;
|
||||
private readonly webhookURLInput: Locator;
|
||||
private readonly webhookDescription: Locator;
|
||||
private readonly deleteButton: Locator;
|
||||
|
||||
constructor(public readonly page: Page) {
|
||||
this.page = page;
|
||||
this.createWebhookButton = page.getByRole('link', {
|
||||
name: 'Create Webhook',
|
||||
});
|
||||
this.webhookURLInput = page.getByPlaceholder('URL');
|
||||
this.webhookDescription = page.getByPlaceholder('Write a description');
|
||||
this.deleteButton = page.getByRole('button', { name: 'Delete' });
|
||||
}
|
||||
|
||||
async deleteWebhook() {
|
||||
await this.deleteButton.click();
|
||||
}
|
||||
|
||||
async createWebhook() {
|
||||
await this.createWebhookButton.click();
|
||||
}
|
||||
|
||||
async typeWebhookURL(url: string) {
|
||||
await this.webhookURLInput.clear();
|
||||
await this.webhookURLInput.fill(url);
|
||||
}
|
||||
|
||||
async typeWebhookDescription(description: string) {
|
||||
await this.webhookDescription.fill(description);
|
||||
}
|
||||
|
||||
async selectWebhookObject(index: number, object: string) {
|
||||
await this.page
|
||||
.locator(
|
||||
`//div[aria-controls="object-webhook-type-select-${index}-options"]`,
|
||||
)
|
||||
.click();
|
||||
await this.page.getByRole('option').getByText(object).click();
|
||||
}
|
||||
|
||||
async selectWebhookAction(index: number, action: string) {
|
||||
await this.page
|
||||
.locator(
|
||||
`//div[aria-controls="operation-webhook-type-select-${index}-options"]`,
|
||||
)
|
||||
.click();
|
||||
await this.page.getByRole('option').getByText(action).click();
|
||||
}
|
||||
|
||||
async deleteWebhookFilter(index: number) {
|
||||
await this.page
|
||||
.locator(
|
||||
`//div[aria-controls="object-webhook-type-select-${index}-options"]/../..//button`,
|
||||
)
|
||||
.click();
|
||||
}
|
||||
|
||||
async checkWebhookDetails(name: string) {
|
||||
await this.page.locator(`//a/div[contains(.,'${name}')][first()]`).click();
|
||||
}
|
||||
}
|
||||
@ -9,11 +9,14 @@ export class SettingsPage {
|
||||
private readonly calendarsLink: Locator;
|
||||
private readonly generalLink: Locator;
|
||||
private readonly membersLink: Locator;
|
||||
private readonly rolesLink: Locator;
|
||||
private readonly dataModelLink: Locator;
|
||||
private readonly developersLink: Locator;
|
||||
private readonly functionsLink: Locator;
|
||||
private readonly securityLink: Locator;
|
||||
private readonly integrationsLink: Locator;
|
||||
private readonly securityLink: Locator;
|
||||
private readonly apisLink: Locator;
|
||||
private readonly webhooksLink: Locator;
|
||||
private readonly adminPanelLink: Locator;
|
||||
private readonly labLink: Locator;
|
||||
private readonly releasesLink: Locator;
|
||||
private readonly logoutLink: Locator;
|
||||
private readonly advancedToggle: Locator;
|
||||
@ -28,11 +31,14 @@ export class SettingsPage {
|
||||
this.calendarsLink = page.getByRole('link', { name: 'Calendars' });
|
||||
this.generalLink = page.getByRole('link', { name: 'General' });
|
||||
this.membersLink = page.getByRole('link', { name: 'Members' });
|
||||
this.rolesLink = page.getByRole('link', { name: 'Roles' });
|
||||
this.dataModelLink = page.getByRole('link', { name: 'Data model' });
|
||||
this.developersLink = page.getByRole('link', { name: 'Developers' });
|
||||
this.functionsLink = page.getByRole('link', { name: 'Functions' });
|
||||
this.integrationsLink = page.getByRole('link', { name: 'Integrations' });
|
||||
this.securityLink = page.getByRole('link', { name: 'Security' });
|
||||
this.apisLink = page.getByRole('link', { name: 'APIs' });
|
||||
this.webhooksLink = page.getByRole('link', { name: 'Webhooks' });
|
||||
this.adminPanelLink = page.getByRole('link', { name: 'Admin Panel' });
|
||||
this.labLink = page.getByRole('link', { name: 'Lab' });
|
||||
this.releasesLink = page.getByRole('link', { name: 'Releases' });
|
||||
this.logoutLink = page.getByText('Logout');
|
||||
this.advancedToggle = page.locator('input[type="checkbox"]').first();
|
||||
@ -70,24 +76,36 @@ export class SettingsPage {
|
||||
await this.membersLink.click();
|
||||
}
|
||||
|
||||
async goToRolesSection() {
|
||||
await this.rolesLink.click();
|
||||
}
|
||||
|
||||
async goToDataModelSection() {
|
||||
await this.dataModelLink.click();
|
||||
}
|
||||
|
||||
async goToDevelopersSection() {
|
||||
await this.developersLink.click();
|
||||
}
|
||||
|
||||
async goToFunctionsSection() {
|
||||
await this.functionsLink.click();
|
||||
async goToIntegrationsSection() {
|
||||
await this.integrationsLink.click();
|
||||
}
|
||||
|
||||
async goToSecuritySection() {
|
||||
await this.securityLink.click();
|
||||
}
|
||||
|
||||
async goToIntegrationsSection() {
|
||||
await this.integrationsLink.click();
|
||||
async goToAPIsSection() {
|
||||
await this.apisLink.click();
|
||||
}
|
||||
|
||||
async goToWebhooksSection() {
|
||||
await this.webhooksLink.click();
|
||||
}
|
||||
|
||||
async goToAdminPanelSection() {
|
||||
await this.adminPanelLink.click();
|
||||
}
|
||||
|
||||
async goToLabSection() {
|
||||
await this.labLink.click();
|
||||
}
|
||||
|
||||
async goToReleasesIntegration() {
|
||||
|
||||
@ -6,6 +6,6 @@
|
||||
"private": true,
|
||||
"license": "AGPL-3.0",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.49.0"
|
||||
"@playwright/test": "^1.51.0"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user