Merge remote-tracking branch 'upstream/main' into AUT-1115
This commit is contained in:
6
packages/e2e-tests/.eslintignore
Normal file
6
packages/e2e-tests/.eslintignore
Normal file
@@ -0,0 +1,6 @@
|
||||
node_modules
|
||||
build
|
||||
|
||||
.eslintrc.js
|
||||
|
||||
playwright-report/*
|
25
packages/e2e-tests/.eslintrc.json
Normal file
25
packages/e2e-tests/.eslintrc.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"semi": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"indent": [
|
||||
"error",
|
||||
2
|
||||
]
|
||||
}
|
||||
}
|
@@ -14,6 +14,6 @@ export class DeleteUserModal {
|
||||
async close () {
|
||||
await this.page.click('body', {
|
||||
position: { x: 10, y: 10 }
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
const { AdminCreateRolePage } = require('./create-role-page')
|
||||
const { AdminCreateRolePage } = require('./create-role-page');
|
||||
|
||||
export class AdminEditRolePage extends AdminCreateRolePage {
|
||||
constructor (page) {
|
||||
|
@@ -23,6 +23,7 @@ export class AdminEditUserPage extends AuthenticatedPage {
|
||||
*/
|
||||
async waitForLoad(fullName) {
|
||||
return await this.page.waitForFunction((fullName) => {
|
||||
// eslint-disable-next-line no-undef
|
||||
const el = document.querySelector("[data-test='full-name-input']");
|
||||
return el && el.value === fullName;
|
||||
}, fullName);
|
||||
|
@@ -25,5 +25,5 @@ export const adminFixtures = {
|
||||
adminCreateRolePage: async ({ page}, use) => {
|
||||
await use(new AdminCreateRolePage(page));
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -87,6 +87,7 @@ export class AdminUsersPage extends AuthenticatedPage {
|
||||
await this.firstPageButton.click();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
if (await this.usersLoader.isVisible()) {
|
||||
await this.usersLoader.waitFor({
|
||||
@@ -108,6 +109,7 @@ export class AdminUsersPage extends AuthenticatedPage {
|
||||
|
||||
async getTotalRows() {
|
||||
return await this.page.evaluate(() => {
|
||||
// eslint-disable-next-line no-undef
|
||||
const node = document.querySelector('[data-total-count]');
|
||||
if (node) {
|
||||
const count = Number(node.dataset.totalCount);
|
||||
@@ -121,6 +123,7 @@ export class AdminUsersPage extends AuthenticatedPage {
|
||||
|
||||
async getRowsPerPage() {
|
||||
return await this.page.evaluate(() => {
|
||||
// eslint-disable-next-line no-undef
|
||||
const node = document.querySelector('[data-rows-per-page]');
|
||||
if (node) {
|
||||
const count = Number(node.dataset.rowsPerPage);
|
||||
|
@@ -25,7 +25,7 @@ export class ApplicationsModal extends BasePage {
|
||||
if (this.applications[link] === undefined) {
|
||||
throw {
|
||||
message: `Unknown link "${link}" passed to ApplicationsModal.selectLink`
|
||||
}
|
||||
};
|
||||
}
|
||||
await this.searchInput.fill(link);
|
||||
await this.appListItem.first().click();
|
||||
|
@@ -1,10 +1,11 @@
|
||||
const { BasePage } = require('../../base-page');
|
||||
const { AddGithubConnectionModal } = require('./add-github-connection-modal');
|
||||
const { expect } = require('@playwright/test');
|
||||
|
||||
export class GithubPage extends BasePage {
|
||||
|
||||
constructor (page) {
|
||||
super(page)
|
||||
super(page);
|
||||
this.addConnectionButton = page.getByTestId('add-connection-button');
|
||||
this.connectionsTab = page.getByTestId('connections-tab');
|
||||
this.flowsTab = page.getByTestId('flows-tab');
|
||||
@@ -38,7 +39,7 @@ export class GithubPage extends BasePage {
|
||||
await this.flowsTab.click();
|
||||
await expect(this.flowsTab).toBeVisible();
|
||||
}
|
||||
return await this.flowRows.count() > 0
|
||||
return await this.flowRows.count() > 0;
|
||||
}
|
||||
|
||||
async hasConnections () {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
const { BasePage } = require('../../base-page');
|
||||
const { expect } = require('@playwright/test');
|
||||
|
||||
export class GithubPopup extends BasePage {
|
||||
|
||||
@@ -11,7 +12,7 @@ export class GithubPopup extends BasePage {
|
||||
}
|
||||
|
||||
getPathname () {
|
||||
const url = this.page.url()
|
||||
const url = this.page.url();
|
||||
try {
|
||||
return new URL(url).pathname;
|
||||
} catch (e) {
|
||||
@@ -34,17 +35,17 @@ export class GithubPopup extends BasePage {
|
||||
loginInput.click();
|
||||
await loginInput.fill(process.env.GITHUB_USERNAME);
|
||||
const passwordInput = this.page.getByLabel('Password');
|
||||
passwordInput.click()
|
||||
passwordInput.click();
|
||||
await passwordInput.fill(process.env.GITHUB_PASSWORD);
|
||||
await this.page.getByRole('button', { name: 'Sign in' }).click();
|
||||
// await this.page.waitForTimeout(2000);
|
||||
if (this.page.isClosed()) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
// await this.page.waitForLoadState('networkidle', 30000);
|
||||
this.page.waitForEvent('load');
|
||||
if (this.page.isClosed()) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
await this.page.waitForURL(function (url) {
|
||||
const u = new URL(url);
|
||||
@@ -55,7 +56,7 @@ export class GithubPopup extends BasePage {
|
||||
}
|
||||
|
||||
async handleAuthorize () {
|
||||
if (this.page.isClosed()) { return }
|
||||
if (this.page.isClosed()) { return; }
|
||||
const authorizeButton = this.page.getByRole(
|
||||
'button',
|
||||
{ name: 'Authorize' }
|
||||
@@ -69,7 +70,7 @@ export class GithubPopup extends BasePage {
|
||||
) && (
|
||||
u.searchParams.get('client_id') === null
|
||||
);
|
||||
})
|
||||
});
|
||||
const passwordInput = this.page.getByLabel('Password');
|
||||
if (await passwordInput.isVisible()) {
|
||||
await passwordInput.fill(process.env.GITHUB_PASSWORD);
|
||||
@@ -87,6 +88,6 @@ export class GithubPopup extends BasePage {
|
||||
};
|
||||
}
|
||||
}
|
||||
await this.page.waitForEvent('close')
|
||||
await this.page.waitForEvent('close');
|
||||
}
|
||||
}
|
@@ -1,7 +1,4 @@
|
||||
const path = require('node:path');
|
||||
const { expect } = require('@playwright/test');
|
||||
const { BasePage } = require('./base-page');
|
||||
const { LoginPage } = require('./login-page');
|
||||
|
||||
export class AuthenticatedPage extends BasePage {
|
||||
/**
|
||||
|
@@ -1,4 +1,3 @@
|
||||
const path = require('node:path');
|
||||
const { AuthenticatedPage } = require('./authenticated-page');
|
||||
|
||||
export class ConnectionsPage extends AuthenticatedPage {
|
||||
|
@@ -1,4 +1,3 @@
|
||||
const path = require('node:path');
|
||||
const { AuthenticatedPage } = require('./authenticated-page');
|
||||
|
||||
export class ExecutionsPage extends AuthenticatedPage {
|
||||
|
@@ -1,4 +1,3 @@
|
||||
const path = require('node:path');
|
||||
const { AuthenticatedPage } = require('./authenticated-page');
|
||||
|
||||
export class FlowEditorPage extends AuthenticatedPage {
|
||||
|
@@ -8,6 +8,7 @@ const { LoginPage } = require('./login-page');
|
||||
const { AcceptInvitation } = require('./accept-invitation-page');
|
||||
const { adminFixtures } = require('./admin');
|
||||
const { AdminSetupPage } = require('./admin-setup-page');
|
||||
const { AdminCreateUserPage } = require('./admin/create-user-page');
|
||||
|
||||
exports.test = test.extend({
|
||||
page: async ({ page }, use) => {
|
||||
@@ -58,6 +59,11 @@ exports.publicTest = test.extend({
|
||||
const adminSetupPage = new AdminSetupPage(page);
|
||||
await use(adminSetupPage);
|
||||
},
|
||||
|
||||
adminCreateUserPage: async ({page}, use) => {
|
||||
const adminCreateUserPage = new AdminCreateUserPage(page);
|
||||
await use(adminCreateUserPage);
|
||||
}
|
||||
});
|
||||
|
||||
expect.extend({
|
||||
|
@@ -1,11 +1,11 @@
|
||||
const { Client } = require('pg');
|
||||
|
||||
const client = new Client({
|
||||
host: process.env.POSTGRES_HOST,
|
||||
user: process.env.POSTGRES_USERNAME,
|
||||
port: process.env.POSTGRES_PORT,
|
||||
password: process.env.POSTGRES_PASSWORD,
|
||||
database: process.env.POSTGRES_DATABASE
|
||||
host: process.env.POSTGRES_HOST,
|
||||
user: process.env.POSTGRES_USERNAME,
|
||||
port: process.env.POSTGRES_PORT,
|
||||
password: process.env.POSTGRES_PASSWORD,
|
||||
database: process.env.POSTGRES_DATABASE
|
||||
});
|
||||
|
||||
exports.client = client;
|
||||
|
@@ -1,4 +1,3 @@
|
||||
const path = require('node:path');
|
||||
const { AuthenticatedPage } = require('./authenticated-page');
|
||||
|
||||
export class UserInterfacePage extends AuthenticatedPage {
|
||||
|
@@ -7,7 +7,8 @@
|
||||
"scripts": {
|
||||
"start-mock-license-server": "node ./license-server-with-mock.js",
|
||||
"test": "playwright test",
|
||||
"test:fast": "yarn test -j 90% --quiet --reporter null --ignore-snapshots -x"
|
||||
"test:fast": "yarn test -j 90% --quiet --reporter null --ignore-snapshots -x",
|
||||
"lint": "eslint ."
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
|
@@ -17,7 +17,6 @@ test.describe('Role management page', () => {
|
||||
adminCreateRolePage,
|
||||
adminEditRolePage,
|
||||
adminRolesPage,
|
||||
page,
|
||||
}) => {
|
||||
await test.step('Create a new role', async () => {
|
||||
await adminRolesPage.navigateTo();
|
||||
@@ -126,12 +125,14 @@ test.describe('Role management page', () => {
|
||||
await adminCreateRolePage.isMounted();
|
||||
|
||||
const initScrollTop = await page.evaluate(() => {
|
||||
// eslint-disable-next-line no-undef
|
||||
return document.documentElement.scrollTop;
|
||||
});
|
||||
await page.mouse.move(400, 100);
|
||||
await page.mouse.click(400, 100);
|
||||
await page.mouse.wheel(200, 0);
|
||||
const updatedScrollTop = await page.evaluate(() => {
|
||||
// eslint-disable-next-line no-undef
|
||||
return document.documentElement.scrollTop;
|
||||
});
|
||||
await expect(initScrollTop).not.toBe(updatedScrollTop);
|
||||
@@ -144,11 +145,13 @@ test.describe('Role management page', () => {
|
||||
await adminEditRolePage.isMounted();
|
||||
|
||||
const initScrollTop = await page.evaluate(() => {
|
||||
// eslint-disable-next-line no-undef
|
||||
return document.documentElement.scrollTop;
|
||||
});
|
||||
await page.mouse.move(400, 100);
|
||||
await page.mouse.wheel(200, 0);
|
||||
const updatedScrollTop = await page.evaluate(() => {
|
||||
// eslint-disable-next-line no-undef
|
||||
return document.documentElement.scrollTop;
|
||||
});
|
||||
await expect(initScrollTop).not.toBe(updatedScrollTop);
|
||||
@@ -165,7 +168,6 @@ test.describe('Role management page', () => {
|
||||
adminUsersPage,
|
||||
adminCreateUserPage,
|
||||
adminEditUserPage,
|
||||
page,
|
||||
}) => {
|
||||
await adminRolesPage.navigateTo();
|
||||
await test.step('Create a new role', async () => {
|
||||
@@ -270,7 +272,6 @@ test.describe('Role management page', () => {
|
||||
adminRolesPage,
|
||||
adminUsersPage,
|
||||
adminCreateUserPage,
|
||||
page,
|
||||
}) => {
|
||||
await adminRolesPage.navigateTo();
|
||||
await test.step('Create a new role', async () => {
|
||||
@@ -429,6 +430,7 @@ test('Accessibility of role management page', async ({
|
||||
await page.goto(url);
|
||||
await page.waitForTimeout(750);
|
||||
const isUnmounted = await page.evaluate(() => {
|
||||
// eslint-disable-next-line no-undef
|
||||
const root = document.querySelector('#root');
|
||||
|
||||
if (root) {
|
||||
|
@@ -98,7 +98,7 @@ test.describe('User management page', () => {
|
||||
await expect(userRow).not.toBeVisible(false);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test(
|
||||
'Creating a user which has been deleted',
|
||||
|
@@ -51,7 +51,7 @@ test(
|
||||
|
||||
const subjects = ['Connection', 'Execution', 'Flow'];
|
||||
for (let subject of subjects) {
|
||||
const row = adminCreateRolePage.getSubjectRow(subject)
|
||||
const row = adminCreateRolePage.getSubjectRow(subject);
|
||||
const modal = adminCreateRolePage.getRoleConditionsModal(subject);
|
||||
await adminCreateRolePage.clickPermissionSettings(row);
|
||||
await expect(modal.modal).toBeVisible();
|
||||
|
@@ -2,7 +2,7 @@ const { test, expect } = require('../../fixtures/index');
|
||||
|
||||
// no execution data exists in an empty account
|
||||
test.describe.skip('Executions page', () => {
|
||||
test.beforeEach(async ({ page, executionsPage }) => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.getByTestId('executions-page-drawer-link').click();
|
||||
await page.getByTestId('execution-row').first().click();
|
||||
|
||||
|
@@ -6,7 +6,7 @@ test('Ensure creating a new flow works', async ({ page }) => {
|
||||
await expect(page).toHaveURL(
|
||||
/\/editor\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}/
|
||||
);
|
||||
})
|
||||
});
|
||||
|
||||
test(
|
||||
'Create a new flow with a Scheduler step then an Ntfy step',
|
||||
|
@@ -1,17 +1,8 @@
|
||||
const { AdminCreateUserPage } = require('../../fixtures/admin/create-user-page');
|
||||
const { publicTest, expect } = require('../../fixtures/index');
|
||||
const { client } = require('../../fixtures/postgres-client-config');
|
||||
const { DateTime } = require('luxon');
|
||||
|
||||
publicTest.describe('Accept invitation page', () => {
|
||||
publicTest.beforeAll(async () => {
|
||||
await client.connect();
|
||||
});
|
||||
|
||||
publicTest.afterAll(async () => {
|
||||
await client.end();
|
||||
});
|
||||
|
||||
publicTest('should not be able to set the password if token is empty', async ({ acceptInvitationPage }) => {
|
||||
await acceptInvitationPage.open('');
|
||||
await acceptInvitationPage.excpectSubmitButtonToBeDisabled();
|
||||
@@ -19,44 +10,83 @@ publicTest.describe('Accept invitation page', () => {
|
||||
await acceptInvitationPage.excpectSubmitButtonToBeDisabled();
|
||||
});
|
||||
|
||||
publicTest('should not be able to set the password if token is expired', async ({ acceptInvitationPage, page }) => {
|
||||
const expiredTokenDate = DateTime.now().minus({days: 3}).toISO();
|
||||
const expiredToken = (Math.random() + 1).toString(36).substring(2);
|
||||
|
||||
const adminCreateUserPage = new AdminCreateUserPage(page);
|
||||
adminCreateUserPage.seed(Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER));
|
||||
const user = adminCreateUserPage.generateUser();
|
||||
|
||||
const queryRole = {
|
||||
text: 'SELECT * FROM roles WHERE name = $1',
|
||||
values: ['Admin']
|
||||
};
|
||||
|
||||
try {
|
||||
const queryRoleIdResult = await client.query(queryRole);
|
||||
expect(queryRoleIdResult.rowCount).toEqual(1);
|
||||
|
||||
const insertUser = {
|
||||
text: 'INSERT INTO users (email, full_name, role_id, status, invitation_token, invitation_token_sent_at) VALUES ($1, $2, $3, $4, $5, $6)',
|
||||
values: [user.email, user.fullName, queryRoleIdResult.rows[0].id, 'invited', expiredToken, expiredTokenDate],
|
||||
};
|
||||
|
||||
const insertUserResult = await client.query(insertUser);
|
||||
expect(insertUserResult.rowCount).toBe(1);
|
||||
expect(insertUserResult.command).toBe('INSERT');
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
throw err;
|
||||
}
|
||||
|
||||
await acceptInvitationPage.open(expiredToken);
|
||||
await acceptInvitationPage.acceptInvitation('something');
|
||||
await acceptInvitationPage.expectAlertToBeVisible();
|
||||
});
|
||||
|
||||
publicTest('should not be able to set the password if token is not in db', async ({ acceptInvitationPage }) => {
|
||||
await acceptInvitationPage.open('abc');
|
||||
await acceptInvitationPage.acceptInvitation('something');
|
||||
await acceptInvitationPage.expectAlertToBeVisible();
|
||||
});
|
||||
|
||||
publicTest.describe('Accept invitation page - users', () => {
|
||||
const expiredTokenDate = DateTime.now().minus({days: 3}).toISO();
|
||||
const token = (Math.random() + 1).toString(36).substring(2);
|
||||
|
||||
publicTest.beforeAll(async () => {
|
||||
await client.connect();
|
||||
});
|
||||
|
||||
publicTest.afterAll(async () => {
|
||||
await client.end();
|
||||
});
|
||||
|
||||
publicTest('should not be able to set the password if token is expired', async ({ acceptInvitationPage, adminCreateUserPage }) => {
|
||||
adminCreateUserPage.seed(Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER));
|
||||
const user = adminCreateUserPage.generateUser();
|
||||
|
||||
const queryRole = {
|
||||
text: 'SELECT * FROM roles WHERE name = $1',
|
||||
values: ['Admin']
|
||||
};
|
||||
|
||||
try {
|
||||
const queryRoleIdResult = await client.query(queryRole);
|
||||
expect(queryRoleIdResult.rowCount).toEqual(1);
|
||||
|
||||
const insertUser = {
|
||||
text: 'INSERT INTO users (email, full_name, role_id, status, invitation_token, invitation_token_sent_at) VALUES ($1, $2, $3, $4, $5, $6)',
|
||||
values: [user.email, user.fullName, queryRoleIdResult.rows[0].id, 'invited', token, expiredTokenDate],
|
||||
};
|
||||
|
||||
const insertUserResult = await client.query(insertUser);
|
||||
expect(insertUserResult.rowCount).toBe(1);
|
||||
expect(insertUserResult.command).toBe('INSERT');
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
throw err;
|
||||
}
|
||||
await acceptInvitationPage.open(token);
|
||||
await acceptInvitationPage.acceptInvitation('something');
|
||||
await acceptInvitationPage.expectAlertToBeVisible();
|
||||
});
|
||||
|
||||
publicTest('should not be able to accept invitation if user was soft deleted', async ({ acceptInvitationPage, adminCreateUserPage }) => {
|
||||
const dateNow = DateTime.now().toISO();
|
||||
const user = adminCreateUserPage.generateUser();
|
||||
|
||||
const queryRole = {
|
||||
text: 'SELECT * FROM roles WHERE name = $1',
|
||||
values: ['Admin']
|
||||
};
|
||||
|
||||
try {
|
||||
const queryRoleIdResult = await client.query(queryRole);
|
||||
expect(queryRoleIdResult.rowCount).toEqual(1);
|
||||
|
||||
const insertUser = {
|
||||
text: 'INSERT INTO users (email, full_name, deleted_at, role_id, status, invitation_token, invitation_token_sent_at) VALUES ($1, $2, $3, $4, $5, $6, $7)',
|
||||
values: [user.email, user.fullName, dateNow, queryRoleIdResult.rows[0].id, 'invited', token, dateNow],
|
||||
};
|
||||
|
||||
const insertUserResult = await client.query(insertUser);
|
||||
expect(insertUserResult.rowCount).toBe(1);
|
||||
expect(insertUserResult.command).toBe('INSERT');
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
throw err;
|
||||
}
|
||||
|
||||
await acceptInvitationPage.open(token);
|
||||
await acceptInvitationPage.acceptInvitation('something');
|
||||
await acceptInvitationPage.expectAlertToBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user