From f1d003d551a953a190373d73ee3a23a1796a5b6e Mon Sep 17 00:00:00 2001 From: Vegard Wright Date: Wed, 4 Dec 2024 22:50:11 +0100 Subject: [PATCH] Feature/e2e playwright systemuser 433 (#442) * running scheduled e2e Playwright tests in AT22 and TT02 (until At23 and 24 is ready) * Post to Slack when tests fail --- .github/workflows/scheduled-playwright.yml | 23 +++ .../workflows/template-test-playwright.yml | 18 ++ .gitignore | 2 + .../playwright/api-requests/ApiRequests.tsx | 165 ++++++++++++++++++ frontend/playwright/api-requests/Token.tsx | 82 +++++++++ .../api-requests/global-teardown.tsx | 8 + frontend/playwright/config/.env.at22 | 9 +- frontend/playwright/config/.env.at23 | 9 +- frontend/playwright/config/.env.at24 | 9 +- frontend/playwright/config/.env.tt02 | 9 +- .../e2eTests/approveSystemUserRequest.spec.ts | 49 ++++++ .../e2eTests/deleteSystemUser.spec.ts | 21 +++ .../e2eTests/selectSystemVendor.spec.ts | 10 +- frontend/playwright/package.json | 3 +- frontend/playwright/pages/loginPage.ts | 8 +- frontend/playwright/pages/systemUserPage.ts | 59 +++++-- frontend/playwright/playwright.config.ts | 9 + frontend/playwright/util/TestdataApi.tsx | 23 +++ 18 files changed, 496 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/scheduled-playwright.yml create mode 100644 frontend/playwright/api-requests/ApiRequests.tsx create mode 100644 frontend/playwright/api-requests/Token.tsx create mode 100644 frontend/playwright/api-requests/global-teardown.tsx create mode 100644 frontend/playwright/e2eTests/approveSystemUserRequest.spec.ts create mode 100644 frontend/playwright/e2eTests/deleteSystemUser.spec.ts create mode 100644 frontend/playwright/util/TestdataApi.tsx diff --git a/.github/workflows/scheduled-playwright.yml b/.github/workflows/scheduled-playwright.yml new file mode 100644 index 00000000..21c1feb2 --- /dev/null +++ b/.github/workflows/scheduled-playwright.yml @@ -0,0 +1,23 @@ +name: Playwright tests (Authentication) + +on: + schedule: + # Runs at 7:00 AM UTC every day + - cron: "0 7 * * *" + # Runs at 1:00 PM UTC every day + - cron: "0 13 * * *" + +jobs: + playwright-scheduled: + name: "Scheduled Playwright tests" + uses: ./.github/workflows/template-test-playwright.yml + with: + environment: ${{ matrix.environment }} + strategy: + fail-fast: false + matrix: + environment: [AT22, TT02] + secrets: + USERNAME_TEST_API: ${{ secrets.USERNAME_TEST_API }} + PASSWORD_TEST_API: ${{ secrets.PASSWORD_TEST_API }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/template-test-playwright.yml b/.github/workflows/template-test-playwright.yml index 73e3ab89..e4dba71a 100644 --- a/.github/workflows/template-test-playwright.yml +++ b/.github/workflows/template-test-playwright.yml @@ -7,6 +7,13 @@ on: type: string required: true description: Environment + secrets: + USERNAME_TEST_API: + required: true + PASSWORD_TEST_API: + required: true + SLACK_WEBHOOK_URL: + required: true jobs: playwright: @@ -27,6 +34,17 @@ jobs: - name: Run Playwright tests working-directory: frontend/playwright run: yarn run env:${{ inputs.environment }} + env: + USERNAME_TEST_API: ${{ secrets.USERNAME_TEST_API }} + PASSWORD_TEST_API: ${{ secrets.PASSWORD_TEST_API }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + + - name: Notify Slack on Failure + if: failure() # This step runs only if the previous steps fail + run: | + curl -X POST -H 'Content-type: application/json' --data '{ + "text": ":playwright: Frontend-tester feilet i testmiljø:`${{ inputs.environment }}` på repo: `${{ github.repository }}`. Mer detaljer her: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + }' ${{ secrets.SLACK_WEBHOOK_URL }} - uses: actions/upload-artifact@v4 if: failure() with: diff --git a/.gitignore b/.gitignore index c86f156b..b5a45b13 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ /frontend/playwright/blob-report/ /frontend/playwright/.cache/ /frontend/playwright/.playwright/ +/frontend/playwright/config/.env + # From access management repo: # Yarn stuff; we're not using PnP/Zero installs diff --git a/frontend/playwright/api-requests/ApiRequests.tsx b/frontend/playwright/api-requests/ApiRequests.tsx new file mode 100644 index 00000000..c63b973c --- /dev/null +++ b/frontend/playwright/api-requests/ApiRequests.tsx @@ -0,0 +1,165 @@ +interface PostSystemUserRequestPayload { + systemId: string; + partyOrgNo: string; + externalRef: string; + rights: { + resource: { + id: string; + value: string; + }[]; + }[]; + redirectUrl: string; +} + +export class ApiRequests { + public async cleanUpSystemUsers(systemUsers: { id: string }[], token: string): Promise { + for (const systemuser of systemUsers) { + await this.deleteSystemUser(token, systemuser.id); + } + } + + public async getSystemUsers(token: string): Promise { + const endpoint = `v1/systemuser/${process.env.ALTINN_PARTY_ID}`; + const url = `${process.env.API_BASE_URL}${endpoint}`; + + try { + const response = await fetch(url, { + method: 'GET', + headers: { + Authorization: `Bearer ${token}`, // Use the token for authentication + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + if (response.status === 404) { + console.warn('System users not found (404).'); + return '[]'; //Return empty list if no users to be deleted + } + const errorText = await response.text(); + console.error('Failed to fetch system users:', response.status, errorText); + console.log(response.status); + throw new Error(`Failed to fetch system users: ${response.statusText}`); + } + + const data = await response.json(); // Assuming the API returns JSON data + return JSON.stringify(data, null, 2); // Format the JSON for better readability (optional) + } catch (error) { + console.error('Error fetching system users:', error); + throw new Error('Error fetching system users. Check logs for details.'); + } + } + + public async deleteSystemUser(token: string, systemUserId: string): Promise { + const endpoint = `v1/systemuser/${process.env.ALTINN_PARTY_ID}/${systemUserId}`; + const url = `${process.env.API_BASE_URL}${endpoint}`; + + try { + const response = await fetch(url, { + method: 'DELETE', + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + const errorBody = await response.text(); // Read the error body if needed + console.error('Failed to delete system user:', response.status, errorBody); + throw new Error(`Failed to delete system user: ${response.statusText}`); + } + } catch (error) { + console.error('Error during system user deletion:', error); + throw new Error('System user deletion failed. Check logs for details.'); + } + } + + public async sendPostRequest( + payload: PostSystemUserRequestPayload, + endpoint: string, + token: string, + ): Promise { + const url = `${process.env.API_BASE_URL}${endpoint}`; + + try { + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, // Add the Authorization header + }, + body: JSON.stringify(payload), + }); + + if (!response.ok) { + const errorBody = await response.text(); // Read the response body + console.error(`HTTP Error! Status: ${response.status}, Response Body: ${errorBody}`); + throw new Error(`HTTP error! Status: ${response.status}, Response Body: ${errorBody}`); + } + const data = await response.json(); + return data as Promise; // Return the response data + } catch (error) { + console.error('Error:', error); + throw error; // Rethrow the error to handle it in the test + } + } + + /** + * Sends a GET request to fetch the last system request. + * @param endpoint The API endpoint (relative path). + * @param token The authorization token. + * @returns The response data as JSON. + */ + public async fetchLastSystemRequest(endpoint: string, token: string): Promise { + const url = `${process.env.API_BASE_URL}${endpoint}`; + + try { + const response = await fetch(url, { + method: 'GET', + headers: { + Authorization: `Bearer ${token}`, // Add the Authorization header + }, + }); + + if (!response.ok) { + const errorBody = await response.text(); // Read the response body + console.error(`HTTP Error! Status: ${response.status}, Response Body: ${errorBody}`); + throw new Error(`HTTP error! Status: ${response.status}, Response Body: ${errorBody}`); + } + const data = await response.json(); + return data; // Return the response data + } catch (error) { + console.error('Error:', error); + throw error; // Rethrow the error to handle it in the test + } + } + + generatePayloadSystemUserRequest(): PostSystemUserRequestPayload { + const randomString = Date.now(); // Current timestamp in milliseconds + const randomNum = Math.random().toString(36); + return { + systemId: `${process.env.SYSTEM_ID}`, + partyOrgNo: `${process.env.ORG}`, + externalRef: `${randomNum}${randomString}`, + rights: [ + { + resource: [ + { + value: 'authentication-e2e-test', + id: 'urn:altinn:resource', + }, + ], + }, + { + resource: [ + { + value: 'vegardtestressurs', + id: 'urn:altinn:resource', + }, + ], + }, + ], + redirectUrl: 'https://altinn.no', + }; + } +} \ No newline at end of file diff --git a/frontend/playwright/api-requests/Token.tsx b/frontend/playwright/api-requests/Token.tsx new file mode 100644 index 00000000..a901f525 --- /dev/null +++ b/frontend/playwright/api-requests/Token.tsx @@ -0,0 +1,82 @@ +export class Token { + private readonly username: string; + private readonly password: string; + private readonly org: string; + private readonly environment: string; + + constructor() { + this.username = process.env.USERNAME_TEST_API || ''; + this.password = process.env.PASSWORD_TEST_API || ''; + this.org = process.env.ORG || ''; + this.environment = process.env.environment || ''; + + if (!this.username || !this.password) { + throw new Error('API username or password is not defined in the environment variables.'); + } + + if (!this.org || !this.environment) { + throw new Error('ORG or environment is not defined in the environment variables.'); + } + } + + /** + * Fetches an enterprise Altinn token for a specific organization and environment. + * @param scopes Scopes required for the token. + * @returns The enterprise Altinn token as a string. + */ + public async getEnterpriseAltinnToken(scopes: string): Promise { + // Construct the URL for fetching the enterprise Altinn test token + const url = + `https://altinn-testtools-token-generator.azurewebsites.net/api/GetEnterpriseToken` + + `?orgNo=${process.env.ORG}&env=${process.env.environment}&scopes=${scopes}`; + + const auth = Buffer.from(`${this.username}:${this.password}`).toString('base64'); + const headers = { + Authorization: `Basic ${auth}`, + }; + + // Retrieve the token + const token = await this.getAltinnToken(url, headers); + if (!token) { + throw new Error('Token retrieval failed for Enterprise Altinn token'); + } + + return token; + } + + /** + * Used for fetching an Altinn test token for a specific role + * @returns The Altinn test token as a string + */ + public async getPersonalAltinnToken(scopes = ''): Promise { + // Construct the URL for fetching the Altinn test token + const url = + `https://altinn-testtools-token-generator.azurewebsites.net/api/GetPersonalToken?env=${process.env.environment}` + + `&pid=${process.env.PID}` + + `&userid=${process.env.ALTINN_USER_ID}` + + `&partyid=${process.env.ALTINN_PARTY_ID}` + + `&authLvl=3&ttl=3000` + + (scopes ? `&scopes=${scopes}` : ''); + + // Retrieve the token + const auth = Buffer.from(`${this.username}:${this.password}`).toString('base64'); + const headers = { + Authorization: `Basic ${auth}`, + }; + + const token = await this.getAltinnToken(url, headers); + if (!token) { + throw new Error('Token retrieval failed for Altinn token'); + } + return token; + } + + private async getAltinnToken(url: string, headers: Record): Promise { + const response = await fetch(url, { headers }); + if (!response.ok) { + const errorMessage = await response.text(); // Fetch the full error message from the response + throw new Error(`Failed to fetch token: ${response.statusText} - ${errorMessage}`); + } + return response.text(); + } +} diff --git a/frontend/playwright/api-requests/global-teardown.tsx b/frontend/playwright/api-requests/global-teardown.tsx new file mode 100644 index 00000000..ddd6371e --- /dev/null +++ b/frontend/playwright/api-requests/global-teardown.tsx @@ -0,0 +1,8 @@ +import { TestdataApi } from "playwright/util/TestdataApi"; + +async function globalTeardown() { + console.log('Kjører global opprydding...'); + await TestdataApi.cleanUpTestUsers(); +} + +export default globalTeardown; \ No newline at end of file diff --git a/frontend/playwright/config/.env.at22 b/frontend/playwright/config/.env.at22 index 07bf4a63..992976ed 100644 --- a/frontend/playwright/config/.env.at22 +++ b/frontend/playwright/config/.env.at22 @@ -1,3 +1,10 @@ ENV_NAME="at22" BASE_URL="https://at22.altinn.cloud" -SYSYEMUSER_URL="https://authn.ui.at22.altinn.cloud/authfront/ui/auth/creation" \ No newline at end of file +SYSYEMUSER_URL="https://authn.ui.at22.altinn.cloud/authfront/ui/auth/creation" +API_BASE_URL="https://platform.at22.altinn.cloud/authentication/api/" + +ALTINN_PARTY_ID="51359757" +ALTINN_USER_ID="20010849" +PID="14824497789" +ORG="310547891" +SYSTEM_ID="310547891_E2E - Playwright - Authentication" \ No newline at end of file diff --git a/frontend/playwright/config/.env.at23 b/frontend/playwright/config/.env.at23 index 1c031a00..1e6cc762 100644 --- a/frontend/playwright/config/.env.at23 +++ b/frontend/playwright/config/.env.at23 @@ -1,3 +1,10 @@ ENV_NAME="at23" BASE_URL="https://at23.altinn.cloud" -SYSYEMUSER_URL="https://authn.ui.at23.altinn.cloud/authfront/ui/auth/creation" \ No newline at end of file +SYSYEMUSER_URL="https://authn.ui.at23.altinn.cloud/authfront/ui/auth/creation" +API_BASE_URL="https://platform.at23.altinn.cloud/authentication/api/" + +ALTINN_PARTY_ID="51359757" +ALTINN_USER_ID="20010849" +PID="14824497789" +ORG="310547891" +SYSTEM_ID="310547891_E2E - Playwright - Authentication" \ No newline at end of file diff --git a/frontend/playwright/config/.env.at24 b/frontend/playwright/config/.env.at24 index 1243fb99..11ea32a6 100644 --- a/frontend/playwright/config/.env.at24 +++ b/frontend/playwright/config/.env.at24 @@ -1,3 +1,10 @@ ENV_NAME="at24" BASE_URL="https://at24.altinn.cloud" -SYSYEMUSER_URL="https://authn.ui.at24.altinn.cloud/authfront/ui/auth/creation" \ No newline at end of file +SYSYEMUSER_URL="https://authn.ui.at24.altinn.cloud/authfront/ui/auth/creation" +API_BASE_URL="https://platform.at24.altinn.cloud/authentication/api/" + +ALTINN_PARTY_ID="51359757" +ALTINN_USER_ID="20010849" +PID="14824497789" +ORG="310547891" +SYSTEM_ID="310547891_E2E - Playwright - Authentication" \ No newline at end of file diff --git a/frontend/playwright/config/.env.tt02 b/frontend/playwright/config/.env.tt02 index df30e2f6..96a4d171 100644 --- a/frontend/playwright/config/.env.tt02 +++ b/frontend/playwright/config/.env.tt02 @@ -1,3 +1,10 @@ ENV_NAME="tt02" BASE_URL="https://tt02.altinn.no" -SYSYEMUSER_URL="https://authn.ui.tt02.altinn.no/authfront/ui/auth/creation" \ No newline at end of file +SYSYEMUSER_URL="https://authn.ui.tt02.altinn.no/authfront/ui/auth/creation" +API_BASE_URL="https://platform.tt02.altinn.no/authentication/api/" + +ALTINN_PARTY_ID="51573288" +ALTINN_USER_ID="1260880" +PID="14824497789" +ORG="310547891" +SYSTEM_ID="310547891_E2E - Playwright - Authentication" \ No newline at end of file diff --git a/frontend/playwright/e2eTests/approveSystemUserRequest.spec.ts b/frontend/playwright/e2eTests/approveSystemUserRequest.spec.ts new file mode 100644 index 00000000..c4f602ac --- /dev/null +++ b/frontend/playwright/e2eTests/approveSystemUserRequest.spec.ts @@ -0,0 +1,49 @@ +import test, { expect } from '@playwright/test'; +import { ApiRequests } from '../api-requests/ApiRequests'; +import { Token } from 'playwright/api-requests/Token'; +import { LoginWithUserPage } from 'playwright/pages/loginPage'; + +test.describe('Godkjenn og avvis Systembrukerforespørsel', () => { + let token: Token; + let loginPage: LoginWithUserPage; + let api: ApiRequests; + + test.beforeEach(async ({ page }) => { + api = new ApiRequests(); + token = new Token(); + loginPage = new LoginWithUserPage(page); + }); + + test('Avvis Systembrukerforespørsel', async ({ page }): Promise => { + //Generate confirmUrl from API + const confirmUrl = await prepareSystemUserRequest(api, token); + + await page.goto(confirmUrl); + await page.getByRole('button', { name: 'Avvis' }).click(); + + //Expect user to be logged out + await expect(loginPage.LOGIN_BUTTON).toBeVisible(); + await expect(page).toHaveURL('https://info.altinn.no'); + }); + + test('Godkjenn Systembrukerforespørsel', async ({ page }): Promise => { + const confirmUrl = await prepareSystemUserRequest(api, token); + + await page.goto(confirmUrl); + await page.getByRole('button', { name: 'Godkjenn' }).click(); + + //Expect user to be logged out + await expect(loginPage.LOGIN_BUTTON).toBeVisible(); + await expect(page).toHaveURL('https://info.altinn.no'); + }); + + async function prepareSystemUserRequest(api: ApiRequests, tokenclass: Token) { + const payload = api.generatePayloadSystemUserRequest(); + const scopes = + 'altinn:authentication/systemuser.request.read altinn:authentication/systemuser.request.write'; + const token = await tokenclass.getEnterpriseAltinnToken(scopes); + const endpoint = 'v1/systemuser/request/vendor'; + const apiResponse = await api.sendPostRequest<{ confirmUrl: string }>(payload, endpoint, token); + return apiResponse.confirmUrl; // Return the Confirmation URL to use in the test + } +}); \ No newline at end of file diff --git a/frontend/playwright/e2eTests/deleteSystemUser.spec.ts b/frontend/playwright/e2eTests/deleteSystemUser.spec.ts new file mode 100644 index 00000000..4f0e3f88 --- /dev/null +++ b/frontend/playwright/e2eTests/deleteSystemUser.spec.ts @@ -0,0 +1,21 @@ +import { expect, test } from '@playwright/test'; +import { SystemUserPage } from '../pages/systemUserPage'; + +test('Delete created system user', async ({ page }): Promise => { + const systemUserPage = new SystemUserPage(page); + const system = 'E2E - Playwright - Authentication'; + + // Create new system user + await systemUserPage.selectSystem(system); + await systemUserPage.CREATE_SYSTEM_USER_BUTTON.click(); + await expect(systemUserPage.SYSTEMUSER_CREATED_HEADING).toBeVisible(); + await expect(page.getByText(system).first()).toBeVisible(); + + // Delete system user + await systemUserPage.EDIT_SYSTEMUSER_LINK.click(); + await systemUserPage.DELETE_SYSTEMUSER_BUTTON.click(); + await systemUserPage.FINAL_DELETE_SYSTEMUSER_BUTTON.click(); + + //Back to overview page + await expect(systemUserPage.MAIN_HEADER).toBeVisible(); +}); diff --git a/frontend/playwright/e2eTests/selectSystemVendor.spec.ts b/frontend/playwright/e2eTests/selectSystemVendor.spec.ts index ae56d616..b63d3ae7 100644 --- a/frontend/playwright/e2eTests/selectSystemVendor.spec.ts +++ b/frontend/playwright/e2eTests/selectSystemVendor.spec.ts @@ -1,7 +1,11 @@ -import { test } from '@playwright/test'; +import { expect, test } from '@playwright/test'; import { SystemUserPage } from '../pages/systemUserPage'; -test('should be able to select a system vendor', async ({ page }): Promise => { +test('Create system user and verify landing page', async ({ page }): Promise => { + const system = 'E2E - Playwright - Authentication'; const systemUserPage = new SystemUserPage(page); - await systemUserPage.selectSystemVendor('Tripletex'); + await systemUserPage.selectSystem(system); + await systemUserPage.CREATE_SYSTEM_USER_BUTTON.click(); + await expect(systemUserPage.SYSTEMUSER_CREATED_HEADING).toBeVisible(); + await expect(page.getByText(system).first()).toBeVisible(); }); diff --git a/frontend/playwright/package.json b/frontend/playwright/package.json index cdda563a..72e83914 100644 --- a/frontend/playwright/package.json +++ b/frontend/playwright/package.json @@ -8,7 +8,8 @@ "env:AT21": "cross-env environment=at21 npx playwright test", "env:AT22": "cross-env environment=at22 npx playwright test", "env:AT23": "cross-env environment=at23 npx playwright test", - "env:AT24": "cross-env environment=at24 npx playwright test" + "env:AT24": "cross-env environment=at24 npx playwright test", + "env:TT02": "cross-env environment=tt02 npx playwright test" }, "keywords": [], "author": "", diff --git a/frontend/playwright/pages/loginPage.ts b/frontend/playwright/pages/loginPage.ts index c9933cd7..ba7e978e 100644 --- a/frontend/playwright/pages/loginPage.ts +++ b/frontend/playwright/pages/loginPage.ts @@ -1,9 +1,13 @@ -import { type Page, expect } from '@playwright/test'; +import { Locator, type Page, expect } from '@playwright/test'; const authFile = '.playwright/.auth/user.json'; export class LoginWithUserPage { - constructor(public page: Page) {} + public readonly LOGIN_BUTTON: Locator; + + constructor(public page: Page) { + this.LOGIN_BUTTON = page.locator('span', { hasText: 'Logg inn/Min profil' }); + } async loginAndChooseReportee(testUser: string, reportee: string) { await this.page.goto(`${process.env.BASE_URL}`); diff --git a/frontend/playwright/pages/systemUserPage.ts b/frontend/playwright/pages/systemUserPage.ts index 9dd681cb..d4f3934e 100644 --- a/frontend/playwright/pages/systemUserPage.ts +++ b/frontend/playwright/pages/systemUserPage.ts @@ -1,17 +1,56 @@ -import { type Page, expect } from '@playwright/test'; +import { Locator, type Page, expect } from '@playwright/test'; +import noNb from '../../src/localizations/no_nb.json'; export class SystemUserPage { - constructor(public page: Page) {} + public readonly SELECT_VENDOR_LABEL: Locator; + public readonly CONTINUE_BUTTON: Locator; + public readonly CREATE_SYSTEM_USER_BUTTON: Locator; + public readonly SYSTEMUSER_CREATED_HEADING: Locator; + public readonly EDIT_SYSTEMUSER_LINK: Locator; + public readonly DELETE_SYSTEMUSER_BUTTON: Locator; + public readonly FINAL_DELETE_SYSTEMUSER_BUTTON: Locator; + public readonly CREATE_NEW_SYSTEMUSER_HEADER: Locator; + public readonly MAIN_HEADER: Locator; - async selectSystemVendor(vendorSystem: string) { - await this.page.goto(`${process.env.SYSYEMUSER_URL}`); - await this.page.getByLabel('Velg fagsystem').fill(vendorSystem); - await this.page.getByRole('option', { name: vendorSystem }).click(); - await this.page.getByRole('button', { name: 'Gå videre' }).click(); + constructor(public page: Page) { + this.SELECT_VENDOR_LABEL = this.page.getByLabel(noNb.authent_creationpage.pull_down_menu_label); + this.CONTINUE_BUTTON = this.page.getByRole('button', { + name: noNb.authent_creationpage.confirm_button, + }); + this.CREATE_SYSTEM_USER_BUTTON = this.page.getByRole('button', { + name: noNb.authent_includedrightspage.confirm_button, + }); + this.SYSTEMUSER_CREATED_HEADING = this.page.getByRole('heading', { + name: noNb.authent_overviewpage.created_system_user_title, + }); + + this.EDIT_SYSTEMUSER_LINK = this.page.getByRole('link', { + name: noNb.authent_overviewpage.edit_system_user, + }); + + this.DELETE_SYSTEMUSER_BUTTON = this.page.getByRole('button', { + name: noNb.authent_detailpage.delete_systemuser, + }); - const createButton = this.page.getByRole('button', { - name: 'Opprett systemtilgang', + this.FINAL_DELETE_SYSTEMUSER_BUTTON = this.page.getByRole('dialog').getByRole('button', { + name: noNb.authent_detailpage.delete_systemuser, }); - await expect(createButton).toBeVisible(); + + this.CREATE_NEW_SYSTEMUSER_HEADER = this.page.getByRole('heading', { + name: noNb.authent_overviewpage.sub_title, + }); + + this.MAIN_HEADER = this.page.getByRole('heading', { + name: noNb.authent_overviewpage.banner_title, + }); + } + + async selectSystem(system: string) { + await this.page.goto(`${process.env.SYSYEMUSER_URL}`); + await this.SELECT_VENDOR_LABEL.fill(system); + await this.page.getByLabel(system).click(); + + await this.CONTINUE_BUTTON.click(); + await expect(this.CREATE_SYSTEM_USER_BUTTON).toBeVisible(); } } diff --git a/frontend/playwright/playwright.config.ts b/frontend/playwright/playwright.config.ts index 3932218a..53e687dd 100644 --- a/frontend/playwright/playwright.config.ts +++ b/frontend/playwright/playwright.config.ts @@ -11,11 +11,20 @@ dotenv.config({ path: path.resolve(__dirname, `config/.env.${process.env.environment ?? 'AT22'}`), }); +// Load sensitive credentials from shared `.env` file +dotenv.config({ + path: path.resolve(__dirname, 'config/.env'), +}); + /** * See https://playwright.dev/docs/test-configuration. */ export default defineConfig({ testDir: './e2eTests', + globalTeardown: './api-requests/global-teardown.tsx', + expect: { + timeout: 15_000, + }, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: [ ['dot'], diff --git a/frontend/playwright/util/TestdataApi.tsx b/frontend/playwright/util/TestdataApi.tsx new file mode 100644 index 00000000..17c4e905 --- /dev/null +++ b/frontend/playwright/util/TestdataApi.tsx @@ -0,0 +1,23 @@ +import { ApiRequests } from '../api-requests/ApiRequests'; // Adjust the path based on your project structure +import { Token } from '../api-requests/Token'; // Adjust the path based on your project structure + +export class TestdataApi { + + static async cleanUpTestUsers() { + const api = new ApiRequests(); + const tokenclass = new Token(); + + try { + //cleanup method, dont fail test if this fails but log it + const token = await tokenclass.getPersonalAltinnToken(); + const resp = await api.getSystemUsers(token); + const users = JSON.parse(resp); + + if (users.length > 0) { + await api.cleanUpSystemUsers(users, token); + } + } catch (error) { + console.error('Error during cleanup:', error); + } + } +} \ No newline at end of file