diff --git a/apps/fillForm/tests/E2E/.gitignore b/apps/fillForm/tests/E2E/.gitignore index d60ce5cc..c687d478 100644 --- a/apps/fillForm/tests/E2E/.gitignore +++ b/apps/fillForm/tests/E2E/.gitignore @@ -4,3 +4,4 @@ node_modules/ /playwright-report/ /blob-report/ /playwright/.cache/ +/.auth/ \ No newline at end of file diff --git a/apps/fillForm/tests/E2E/auth.setup.ts b/apps/fillForm/tests/E2E/auth.setup.ts new file mode 100644 index 00000000..2292dd02 --- /dev/null +++ b/apps/fillForm/tests/E2E/auth.setup.ts @@ -0,0 +1,24 @@ +import { test as setup } from '@playwright/test'; +import {fillFormAppPageForAdmin, fillFormAppPageForUser} from "/tests/E2E/tests/fixtures/fillFormApp"; + +const adminFile = '.auth/admin.json'; + +setup('authenticate as admin', async ({ page }) => { + const fillFormAppPageAsAdmin = new fillFormAppPageForAdmin(page); + + await fillFormAppPageAsAdmin.login() + + // save context for later + await page.context().storageState({ path: adminFile }); +}); + +const userFile = '.auth/user.json'; + +setup('authenticate as user', async ({ page }) => { + const fillFormAppPageAsUser = new fillFormAppPageForUser(page); + + await fillFormAppPageAsUser.login() + + // save context for later + await page.context().storageState({ path: userFile }); +}); diff --git a/apps/fillForm/tests/E2E/global-setup.ts b/apps/fillForm/tests/E2E/global-setup.ts new file mode 100644 index 00000000..d4986426 --- /dev/null +++ b/apps/fillForm/tests/E2E/global-setup.ts @@ -0,0 +1,89 @@ +import {Page, expect, firefox, type FullConfig } from '@playwright/test'; +import { writeFileSync } from 'node:fs'; + + +const adminFile = '.auth/admin.json'; +const userFile = '.auth/user.json'; + +const fillSciperFieldsWithEnv = async (page: Page) => { + if (process.env.CONNECT_AS_SCIPER) { + await page.getByLabel('SCIPER:').click(); + await page.getByLabel('SCIPER:').fill(process.env.CONNECT_AS_SCIPER); + } +} + +const fillNameFieldsWithEnv = async (page: Page) => { + if (process.env.CONNECT_AS_NAME) { + await page.getByLabel('Display name:').click(); + await page.getByLabel('Display name:').fill(process.env.CONNECT_AS_NAME); + } +} + +const fillGroupsFieldsWithEnv = async (page: Page) => { + if (process.env.CONNECT_AS_GROUPS) { + await page.getByLabel('Groups (comma separated):').click(); + await page.getByLabel('Groups (comma separated):').fill(process.env.CONNECT_AS_GROUPS); + } +} + +async function globalSetup(config: FullConfig) { + console.log('Logging as admin...'); + const { baseURL } = config.projects[0].use; + const browser = await firefox.launch(); + + const adminContext = await browser.newContext({ + ignoreHTTPSErrors: true, + }); + const adminPage = await adminContext.newPage(); + + await adminPage.goto(baseURL!); + await adminPage.waitForURL((url) => url.href.includes('cgi-bin/tequila/auth')) + + await fillSciperFieldsWithEnv(adminPage); + await fillNameFieldsWithEnv(adminPage); + + await adminPage.getByRole('button', { name: 'Submit' }).click() + await adminPage.waitForURL(baseURL!) + // once near-fully loaded, we can see the user info button + await expect(adminPage.locator('#user-info-button')).toBeVisible(); + + // save context for later + await adminPage.context().storageState({ path: adminFile }); + + /** + * USER + */ + console.log('Logging as user...'); + // userContext and all pages inside, including userPage, are signed in as "user". + const userContext = await browser.newContext({ + ignoreHTTPSErrors: true, + }); + const userPage = await userContext.newPage(); + + await userPage.goto(baseURL!); + await userPage.waitForURL((url) => url.href.includes('cgi-bin/tequila/auth')); + + await fillSciperFieldsWithEnv(userPage); + await fillNameFieldsWithEnv(userPage); + await fillGroupsFieldsWithEnv(userPage); + + await userPage.getByText('Groups (comma separated):').click(); + await userPage.getByLabel('Groups (comma separated):').fill(''); + await userPage.getByRole('button', { name: 'Submit' }).click() + await userPage.waitForURL(baseURL!) + // once near-fully loaded, we can see the user info button + await expect(userPage.locator('#user-info-button')).toBeVisible(); + + // save context for later + await userPage.context().storageState({ path: userFile }); + + // Get session storage and store as env variable + const sessionStorageUser: any = await userPage.evaluate(() => JSON.stringify(sessionStorage)); + writeFileSync('.auth/user_session.json', JSON.stringify(sessionStorageUser), 'utf-8'); + console.log(`All done for the user. saving the context into ${userFile}...`); + + // end the browser as tests will start fresh + await browser.close(); +} + +export default globalSetup; diff --git a/apps/fillForm/tests/E2E/playwright.config.ts b/apps/fillForm/tests/E2E/playwright.config.ts index ec897717..43df3b43 100644 --- a/apps/fillForm/tests/E2E/playwright.config.ts +++ b/apps/fillForm/tests/E2E/playwright.config.ts @@ -16,7 +16,7 @@ export default defineConfig({ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ // workers: process.env.CI ? 1 : undefined, - workers: 1, + //workers: 1, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: 'html', /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ @@ -30,6 +30,8 @@ export default defineConfig({ ignoreHTTPSErrors: true, }, + globalSetup: require.resolve('./global-setup'), + /* Configure projects for major browsers */ projects: [ { diff --git a/apps/fillForm/tests/E2E/tests/fixtures/index.ts b/apps/fillForm/tests/E2E/tests/fixtures/index.ts index 2d4a1e3d..3f086abb 100644 --- a/apps/fillForm/tests/E2E/tests/fixtures/index.ts +++ b/apps/fillForm/tests/E2E/tests/fixtures/index.ts @@ -1,4 +1,4 @@ -import {Browser, Page, test as base} from '@playwright/test'; +import {Browser, BrowserContext, Page, test as base} from '@playwright/test'; import {fillFormAppPageForUser, fillFormAppPageForAdmin} from "/tests/E2E/tests/fixtures/fillFormApp"; import {loginAsAdmin} from "/tests/E2E/tests/utils/login"; @@ -10,19 +10,21 @@ type FillFormAppFixtures = { }; export const test = base.extend({ - fillFormAppPageAsUser: async ({ page }, use) => { - const fillFormAppPageAsUser = new fillFormAppPageForUser(page); - - await fillFormAppPageAsUser.login() + fillFormAppPageAsUser: async ({ browser }, use) => { + const context = await browser.newContext({ storageState: '.auth/user.json' }); + const fillFormAppPageAsUser = new fillFormAppPageForUser(await context.newPage()); await use(fillFormAppPageAsUser); - }, - fillFormAppPageAsAdmin: async ({ page }, use) => { - const fillFormAppPageAsAdmin = new fillFormAppPageForAdmin(page); - await fillFormAppPageAsAdmin.login() + await context.close(); + }, + fillFormAppPageAsAdmin: async ({ browser }, use) => { + const context = await browser.newContext({ storageState: '.auth/admin.json' }); + const fillFormAppPageAsAdmin = new fillFormAppPageForAdmin(await context.newPage()); await use(fillFormAppPageAsAdmin); + + await context.close(); }, }); @@ -59,3 +61,27 @@ export const cleanupPageAndTaskForUser = async (page: Page) => { await fillFormAppPageAsAdmin.removeAllTasks(); await fillFormAppPageAsAdmin.page.close(); } + +export const setupUserAndAdminContexts = async (browser: Browser) => { + // adminContext and all pages inside, including adminPage, are signed in as "admin". + const adminContext = await browser.newContext({ storageState: '.auth/admin.json' }); + const adminPage = await adminContext.newPage(); + + // userContext and all pages inside, including userPage, are signed in as "user". + const userContext = await browser.newContext({ storageState: '.auth/user.json' }); + const userPage = await userContext.newPage(); + + return { + adminContext, + adminPage, + userContext, + userPage, + } +} + +export const tearDownUserAndAdminContexts = async ( + adminContext: BrowserContext, userContext: BrowserContext +) => { + await adminContext.close(); + await userContext.close(); +} diff --git a/apps/fillForm/tests/E2E/tests/user.spec.ts b/apps/fillForm/tests/E2E/tests/user.spec.ts index 6234c50a..9381ea55 100644 --- a/apps/fillForm/tests/E2E/tests/user.spec.ts +++ b/apps/fillForm/tests/E2E/tests/user.spec.ts @@ -1,7 +1,6 @@ import {expect} from '@playwright/test'; import { cleanupPageAndTaskForUser, - setupAPagWithTasksForUser, test } from './fixtures'; import {fillFormAppPageForUser} from "/tests/E2E/tests/fixtures/fillFormApp"; @@ -10,13 +9,45 @@ import {fillFormAppPageForUser} from "/tests/E2E/tests/fixtures/fillFormApp"; let userApp: fillFormAppPageForUser; test.beforeAll(async ({ browser }) => { - userApp = await setupAPagWithTasksForUser(browser); + //userApp = await setupAPagWithTasksForUser(browser); }); -test.afterAll(async () => { - await cleanupPageAndTaskForUser(userApp.page); +// test.afterAll(async () => { +// await cleanupPageAndTaskForUser(userApp.page); +// }); + + +test('admin and user', async ({ browser }) => { + // adminContext and all pages inside, including adminPage, are signed in as "admin". + const adminContext = await browser.newContext({ storageState: '.auth/admin.json' }); + const adminPage = await adminContext.newPage(); + + // userContext and all pages inside, including userPage, are signed in as "user". + const userContext = await browser.newContext({ storageState: '.auth/user.json' }); + const userPage = await userContext.newPage(); + + await adminPage.goto('/'); + await adminPage.locator('#user-info-button').click() + await expect(adminPage.locator('#user-info-displayname')).toBeVisible(); + + await userPage.goto('/'); + await userPage.locator('#user-info-button').click() + await expect(userPage.locator('#user-info-displayname')).not.toBeVisible(); + + await adminContext.close(); + await userContext.close(); }); +test('admin and user should flagged good', async ({ fillFormAppPageAsUser, fillFormAppPageAsAdmin, }) => { + await fillFormAppPageAsAdmin.page.goto('/'); + await fillFormAppPageAsAdmin.page.locator('#user-info-button').click() + await expect(fillFormAppPageAsAdmin.page.locator('#user-info-displayname')).toBeVisible(); + + await fillFormAppPageAsUser.page.goto('/'); + await fillFormAppPageAsUser.page.locator('#user-info-button').click() + await expect(fillFormAppPageAsUser.page.locator('#user-info-displayname')).not.toBeVisible(); + +}); test('I should not be flagged as admin', async ({ fillFormAppPageAsUser }) => { await fillFormAppPageAsUser.page.locator('#user-info-button').click()