Skip to content

Commit

Permalink
[test] Improve our integration tests
Browse files Browse the repository at this point in the history
Signed-off-by: Stéphane Bégaudeau <[email protected]>
  • Loading branch information
sbegaudeau committed Sep 6, 2023
1 parent 77fa476 commit ca98e62
Show file tree
Hide file tree
Showing 19 changed files with 443 additions and 36 deletions.
2 changes: 1 addition & 1 deletion frontend/svalyn-studio-app/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const config: PlaywrightTestConfig = {
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000
timeout: 20 * 1000,
},
/* Run tests in files in parallel */
fullyParallel: true,
Expand Down
30 changes: 30 additions & 0 deletions frontend/svalyn-studio-app/tests/e2e/admin/manage-accounts.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2022, 2023 Stéphane Bégaudeau.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { test } from '../../fixture';

test.describe('Manage accounts', () => {
test('should let me view the accounts created', async ({ loginPage, userMenu }) => {
await loginPage.goto();
await loginPage.login('admin', 'password');

await userMenu.open();
await userMenu.gotoAdmin();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
*/

import { expect } from '@playwright/test';
import { test } from '../fixture';
import { test } from '../../fixture';

test.describe('Login view', () => {
test.describe('Authenticate', () => {
test('should let me log in with Github', async ({ page }) => {
await page.goto('http://localhost:5173/login');

Expand All @@ -38,14 +38,15 @@ test.describe('Login view', () => {
await expect(page).toHaveURL('http://localhost:5173');
});

test('should let me log in and then log out', async ({ page, loginPage }) => {
test('should let me log in and then log out', async ({ page, loginPage, userMenu }) => {
await loginPage.goto();
await loginPage.login('admin', 'password');

await expect(page).toHaveURL('http://localhost:5173');

await page.getByTestId('user-menu-avatar').click();
await page.getByRole('menuitem', { name: 'Sign out' }).click();
await userMenu.open();
await userMenu.logout();

await expect(page).toHaveURL('http://localhost:5173/login');
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
*/

import { expect } from '@playwright/test';
import { test } from '../fixture';
import { test } from '../../fixture';

test.describe('New organization view', () => {
test.describe('Create organization', () => {
test.beforeEach(async ({ loginPage }) => {
await loginPage.goto();
await loginPage.loginAsAdmin();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2022, 2023 Stéphane Bégaudeau.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { expect } from '@playwright/test';
import { test } from '../../fixture';
import { Organization } from '../../fixture.types';

test.describe('Update organization members', () => {
let organization: Organization;

test.beforeEach(async ({ loginPage, newOrganizationPage }) => {
await loginPage.goto();
await loginPage.loginAsAdmin();

await newOrganizationPage.goto();
organization = await newOrganizationPage.createOrganization();
});

test.afterEach(async ({ organizationSettingsPage }) => {
await organizationSettingsPage.goto(organization.identifier);
await organizationSettingsPage.delete();
});

test('should have the creator of the project has a member', async ({ organizationMembersPage, page }) => {
await organizationMembersPage.goto(organization.identifier);
await expect(page.getByRole('cell', { name: 'Admin Admin' })).toBeVisible();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
*/

import { expect } from '@playwright/test';
import { test } from '../fixture';
import { Organization } from '../fixture.types';
import { test } from '../../fixture';
import { Organization } from '../../fixture.types';

test.describe('Organization settings view', () => {
test.describe('Update organization', () => {
let organization: Organization;

test.beforeEach(async ({ loginPage, newOrganizationPage }) => {
Expand All @@ -37,14 +37,12 @@ test.describe('Organization settings view', () => {
await organizationSettingsPage.delete();
});

test('should let me update the organization name', async ({ page }) => {
test('should let me update the organization name', async ({ page, organizationSettingsPage }) => {
await page.goto(`http://localhost:5173/orgs/${organization.identifier}`);
await expect(page.getByRole('heading', { name: organization.name })).toBeVisible();

await page.getByRole('tab').filter({ hasText: 'SETTINGS' }).click();
await page.getByRole('textbox', { name: 'Organization Name' }).fill(`Renamed ${organization.name}`);
await page.getByRole('button', { name: 'RENAME' }).click();

await expect(page.getByRole('heading', { name: `Renamed ${organization.name}` })).toBeVisible();
await organizationSettingsPage.rename(`Renamed ${organization.name}`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
*/

import { expect } from '@playwright/test';
import { test } from '../fixture';
import { Organization } from '../fixture.types';
import { test } from '../../fixture';
import { Organization } from '../../fixture.types';

test.describe('New project view', () => {
test.describe('Create project', () => {
let organization: Organization;

test.beforeEach(async ({ loginPage, newOrganizationPage }) => {
Expand All @@ -37,19 +37,12 @@ test.describe('New project view', () => {
await organizationSettingsPage.delete();
});

test('should let me create a project', async ({ page, browserName }) => {
test('should let me create a project', async ({ page, organizationPage }) => {
await organizationPage.goto(organization.identifier);
await page.goto(`http://localhost:5173/orgs/${organization.identifier}`);

await expect(page.getByRole('heading', { name: organization.name })).toBeVisible();
const project = await organizationPage.createProject();

await page.getByRole('button', { name: 'NEW PROJECT' }).click();
await page.getByRole('textbox', { name: 'Project Name' }).fill(`New project view ${browserName}`);
await page.getByRole('textbox', { name: 'Project Identifier' }).fill(`creating-project-view-${browserName}`);
await page
.getByRole('textbox', { name: 'Project Description' })
.fill(`New project view description ${browserName}`);
await page.getByRole('button', { name: 'CREATE' }).click();

await expect(page).toHaveURL(`http://localhost:5173/projects/creating-project-view-${browserName}`);
await expect(page).toHaveURL(`http://localhost:5173/projects/${project.identifier}`);
});
});
44 changes: 42 additions & 2 deletions frontend/svalyn-studio-app/tests/fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,40 @@
*/
import { test as base } from '@playwright/test';
import { Fixture } from './fixture.types';
import { HomePage } from './pages/HomePage';
import { LoginPage } from './pages/LoginPage';
import { NewOrganizationPage } from './pages/NewOrganizationPage';
import { OrganizationPage } from './pages/OrganizationPage';
import { OrganizationSettingsPage } from './pages/OrganizationSettingsPage';
import { AdminAccountsPage } from './pages/admin/AdminAccountsPage';
import { AdminNewAccountPage } from './pages/admin/AdminNewAccountPage';
import { OrganizationMembersPage } from './pages/organization/OrganizationMembersPage';
import { OrganizationPage } from './pages/organization/OrganizationPage';
import { OrganizationSettingsPage } from './pages/organization/OrganizationSettingsPage';
import { InvitationsPage } from './pages/profile/InvitationsPage';
import { ProfilePage } from './pages/profile/ProfilePage';
import { SettingsPage } from './pages/profile/SettingsPage';
import { UserMenu } from './widgets/UserMenu';

export const test = base.extend<Fixture>({
loginPage: async ({ page }, use) => {
await use(new LoginPage(page));
},

homePage: async ({ page }, use) => {
await use(new HomePage(page));
},

profilePage: async ({ page }, use) => {
await use(new ProfilePage(page, ''));
},

invitationsPage: async ({ page }, use) => {
await use(new InvitationsPage(page));
},

settingsPage: async ({ page }, use) => {
await use(new SettingsPage(page));
},

newOrganizationPage: async ({ page }, use) => {
await use(new NewOrganizationPage(page));
},
Expand All @@ -36,7 +60,23 @@ export const test = base.extend<Fixture>({
await use(new OrganizationPage(page, ''));
},

organizationMembersPage: async ({ page }, use) => {
await use(new OrganizationMembersPage(page, ''));
},

organizationSettingsPage: async ({ page }, use) => {
await use(new OrganizationSettingsPage(page, ''));
},

adminAccountsPage: async ({ page }, use) => {
await use(new AdminAccountsPage(page));
},

adminNewAccountPage: async ({ page }, use) => {
await use(new AdminNewAccountPage(page));
},

userMenu: async ({ page }, use) => {
await use(new UserMenu(page));
},
});
21 changes: 19 additions & 2 deletions frontend/svalyn-studio-app/tests/fixture.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,33 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { HomePage } from './pages/HomePage';
import { LoginPage } from './pages/LoginPage';
import { NewOrganizationPage } from './pages/NewOrganizationPage';
import { OrganizationPage } from './pages/OrganizationPage';
import { OrganizationSettingsPage } from './pages/OrganizationSettingsPage';
import { AdminAccountsPage } from './pages/admin/AdminAccountsPage';
import { AdminNewAccountPage } from './pages/admin/AdminNewAccountPage';
import { OrganizationMembersPage } from './pages/organization/OrganizationMembersPage';
import { OrganizationPage } from './pages/organization/OrganizationPage';
import { OrganizationSettingsPage } from './pages/organization/OrganizationSettingsPage';
import { InvitationsPage } from './pages/profile/InvitationsPage';
import { ProfilePage } from './pages/profile/ProfilePage';
import { SettingsPage } from './pages/profile/SettingsPage';
import { UserMenu } from './widgets/UserMenu';

export type Fixture = {
loginPage: LoginPage;
homePage: HomePage;
profilePage: ProfilePage;
invitationsPage: InvitationsPage;
settingsPage: SettingsPage;
newOrganizationPage: NewOrganizationPage;
organizationPage: OrganizationPage;
organizationMembersPage: OrganizationMembersPage;
organizationSettingsPage: OrganizationSettingsPage;
adminAccountsPage: AdminAccountsPage;
adminNewAccountPage: AdminNewAccountPage;

userMenu: UserMenu;
};

export type Organization = {
Expand Down
28 changes: 28 additions & 0 deletions frontend/svalyn-studio-app/tests/pages/HomePage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2023 Stéphane Bégaudeau.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { Page } from '@playwright/test';

export class HomePage {
constructor(public readonly page: Page) {}

async goto() {
await this.page.goto('http://localhost:5173/');
}
}
28 changes: 28 additions & 0 deletions frontend/svalyn-studio-app/tests/pages/admin/AdminAccountsPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2023 Stéphane Bégaudeau.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { Page } from '@playwright/test';

export class AdminAccountsPage {
constructor(public readonly page: Page) {}

async goto() {
await this.page.goto('http://localhost:5173/admin/accounts');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2023 Stéphane Bégaudeau.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

import { Page } from '@playwright/test';

export class AdminNewAccountPage {
constructor(public readonly page: Page) {}

async goto() {
await this.page.goto('http://localhost:5173/admin/new/account');
}
}
Loading

0 comments on commit ca98e62

Please sign in to comment.