Skip to content

Commit

Permalink
add loginpage and reviewer auth to e2e setup
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminpaige committed Jan 22, 2024
1 parent 63abb97 commit 4e0ab98
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ build_run
.turbo
coverage
lambda_layer.zip
**/.auth/user.json
**/.auth/*.json
1 change: 1 addition & 0 deletions src/services/ui/e2e/pages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./loginPage";
21 changes: 21 additions & 0 deletions src/services/ui/e2e/pages/loginPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Page, expect } from "@playwright/test";

export class LoginPage {
constructor(private readonly page: Page) {}

async goto() {
await this.page.goto("/");
await this.page.getByRole("button", { name: "Sign In" }).click();
}

async login(email: string, password: string) {
await this.goto();
await this.page.getByRole("textbox", { name: "[email protected]" }).fill(email);
await this.page.getByRole("textbox", { name: "Password" }).fill(password);
await this.page.getByRole("button", { name: "submit" }).click();
await this.page.waitForLoadState("networkidle");
expect(
await this.page.getByRole("link", { name: "Dashboard" })
).toBeVisible();
}
}
28 changes: 16 additions & 12 deletions src/services/ui/e2e/tests/a11y/homepage.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { test, expect } from "@playwright/test";
import AxeBuilder from "@axe-core/playwright";

// this could be repeated for every page we want to test a11y for.
// we could also have a list of paths to test and loop through them ie ['/', 'dashboard', 'faq'] etc
const staticRoutes = ["/", "/dashboard", "/faq", "/profile"];

test.describe("homepage", () => {
test("should not have any automatically detectable accessibility issues", async ({
page,
}) => {
await page.goto("/");
await page.waitForLoadState("networkidle"); // playwright is so fast this is sometimes helpful to slow it down to view results
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
console.log("violations: ", accessibilityScanResults.violations.length);
expect(accessibilityScanResults.violations).toEqual([]);
});
test.describe("test a11y on static routes", () => {
for (const route of staticRoutes) {
test(`${route} should not have any automatically detectable accessibility issues`, async ({
page,
}) => {
await page.goto(route);
await page.waitForLoadState("networkidle"); // playwright is so fast this is sometimes helpful to slow it down to view results
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
console.log(
`${route} violations: `,
accessibilityScanResults.violations.length
);
expect(accessibilityScanResults.violations).toEqual([]);
});
}
});
29 changes: 17 additions & 12 deletions src/services/ui/e2e/utils/auth.setup.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { test as setup } from "@playwright/test";
import * as Libs from "../../../../libs/secrets-manager-lib";
import { testUsers } from "./users";
import { LoginPage } from "../pages";

const stage =
process.env.STAGE_NAME === "production" || process.env.STAGE_NAME === "val"
Expand All @@ -13,18 +14,22 @@ const password = (await Libs.getSecretsValue(
secretId
)) as string;

const authFile = "playwright/.auth/user.json";
const stateSubmitterAuthFile = "playwright/.auth/state-user.json";

setup("authenticate", async ({ page }) => {
await page.goto("/");
await page.getByRole("button", { name: "Sign In" }).click();
await page
.getByRole("textbox", { name: "[email protected]" })
.fill(testUsers.state);
await page.getByRole("textbox", { name: "Password" }).fill(password);
await page.getByRole("button", { name: "submit" }).click();
await page.getByRole("link", { name: "Dashboard" }).click();
// End of authentication steps.
setup("authenticate state submitter", async ({ page, context }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();

await page.context().storageState({ path: authFile });
await loginPage.login(testUsers.state, password);
await context.storageState({ path: stateSubmitterAuthFile });
});

const reviewerAuthFile = "playwright/.auth/reviewer-user.json";

setup("authenticate cms reviewer", async ({ page, context }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();

await loginPage.login(testUsers.reviewer, password);
await context.storageState({ path: reviewerAuthFile });
});
6 changes: 3 additions & 3 deletions src/services/ui/e2e/utils/users.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const testUsers = {
state: "[email protected]",
cmsAdmin: "cmsadmin@example.com"
};
state: "[email protected]",
reviewer: "reviewer@example.com",
};
6 changes: 3 additions & 3 deletions src/services/ui/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ export default defineConfig({
// Note: we can test on multiple browsers and resolutions defined here
projects: [
// Setup project
{ name: "setup", testMatch: /.*\.setup\.ts/ },
{ name: "setup", testMatch: /.*\.setup\.ts/, fullyParallel: true },

{
// we can have different projects for different users/use cases
name: "logged in state user",
use: {
...devices["Desktop Chrome"],
// Use prepared auth state.
storageState: "playwright/.auth/user.json",
// Use prepared auth state for state submitter.
storageState: "playwright/.auth/state-user.json",
},
// Tests start already authenticated because we specified storageState in the config.
dependencies: ["setup"],
Expand Down
3 changes: 2 additions & 1 deletion src/services/ui/src/pages/profile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ export const Profile = () => {
</SubNavHeader>

<section className="block max-w-screen-xl m-auto px-4 lg:px-8 py-8 gap-10">
<Alert className="mb-6 bg-sky-100 flex flex-row">
{/* using bg-sky-50 for a11y compliance */}
<Alert className="mb-6 bg-sky-50 flex flex-row">
<div className="py-1 mr-2 flex-none w-8">
<svg
xmlns="http://www.w3.org/2000/svg"
Expand Down

0 comments on commit 4e0ab98

Please sign in to comment.