Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# Get all staged files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR)

if [ -n "$STAGED_FILES" ]; then
echo "Running lint with fix on staged files..."
# Run lint on all files (modifies files in the working directory)
yarn lint --fix
yarn prettier:write

echo "Re-adding originally staged files to the staging area..."
# Re-add only the originally staged files
Expand Down
56 changes: 0 additions & 56 deletions e2e/base.ts

This file was deleted.

20 changes: 0 additions & 20 deletions e2e/tests/login.spec.ts

This file was deleted.

4 changes: 2 additions & 2 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './e2e/tests',
testDir: './tests/e2e/',
/* Run tests in files in parallel */
fullyParallel: false,
/* Fail the build on CI if you accidentally left test.only in the source code. */
Expand All @@ -11,7 +11,7 @@ export default defineConfig({
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
reporter: process.env.CI ? 'github' : 'html',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
Expand Down
2 changes: 1 addition & 1 deletion src/ui/pages/events/ViewEvents.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export const ViewEventsPage: React.FC = () => {
{showPrevious ? 'Hide Previous Events' : 'Show Previous Events'}
</Button>
</div>
<Table style={{ tableLayout: 'fixed', width: '100%' }}>
<Table style={{ tableLayout: 'fixed', width: '100%' }} data-testid="events-table">
<Table.Thead>
<Table.Tr>
<Table.Th>Title</Table.Th>
Expand Down
82 changes: 82 additions & 0 deletions tests/e2e/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { test as base } from "@playwright/test";
import {
SecretsManagerClient,
GetSecretValueCommand,
} from "@aws-sdk/client-secrets-manager";

export const getSecretValue = async (
secretId: string,
): Promise<Record<string, string | number | boolean> | null> => {
const smClient = new SecretsManagerClient();
const data = await smClient.send(
new GetSecretValueCommand({ SecretId: secretId }),
);
if (!data.SecretString) {
return null;
}
try {
return JSON.parse(data.SecretString) as Record<
string,
string | number | boolean
>;
} catch {
return null;
}
};

async function getSecrets() {
let response = { PLAYWRIGHT_USERNAME: "", PLAYWRIGHT_PASSWORD: "" };
let keyData;
if (!process.env.PLAYWRIGHT_USERNAME || !process.env.PLAYWRIGHT_PASSWORD) {
keyData = await getSecretValue("infra-core-api-config");
}
response["PLAYWRIGHT_USERNAME"] =
process.env.PLAYWRIGHT_USERNAME ||
(keyData ? keyData["playwright_username"] : "");
response["PLAYWRIGHT_PASSWORD"] =
process.env.PLAYWRIGHT_PASSWORD ||
(keyData ? keyData["playwright_password"] : "");
return response;
}

const secrets = await getSecrets();

export function capitalizeFirstLetter(string: string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

async function becomeUser(page) {
await page.goto("https://manage.qa.acmuiuc.org/login");
await page
.getByRole("button", { name: "Sign in with Illinois NetID" })
.click();
await page.getByPlaceholder("NetID@illinois.edu").click();
await page
.getByPlaceholder("NetID@illinois.edu")
.fill(secrets["PLAYWRIGHT_USERNAME"]);
await page.getByPlaceholder("NetID@illinois.edu").press("Enter");
await page.getByPlaceholder("Password").click();
await page.getByPlaceholder("Password").fill(secrets["PLAYWRIGHT_PASSWORD"]);
await page.getByRole("button", { name: "Sign in" }).click();
await page.getByRole("button", { name: "No" }).click();
}

export async function getUpcomingEvents() {
const data = await fetch(
"https://infra-core-api.aws.qa.acmuiuc.org/api/v1/events?upcomingOnly=true",
);
return (await data.json()) as Record<string, string>[];
}

export async function getAllEvents() {
const data = await fetch(
"https://infra-core-api.aws.qa.acmuiuc.org/api/v1/events",
);
return (await data.json()) as Record<string, string>[];
}

export const test = base.extend<{ becomeUser: (page) => Promise<void> }>({
becomeUser: async ({}, use) => {
use(becomeUser);
},
});
48 changes: 48 additions & 0 deletions tests/e2e/events.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { expect } from "@playwright/test";
import { capitalizeFirstLetter, getUpcomingEvents, test } from "./base";
import { describe } from "node:test";

describe("Events tests", () => {
test("A user can login and view the upcoming events", async ({
page,
becomeUser,
}) => {
await becomeUser(page);
await page.locator("a").filter({ hasText: "Events" }).click();
await expect(page.getByRole("heading")).toContainText(
"Core Management Service (NonProd)",
);
await expect(
page.getByRole("button", { name: "New Calendar Event" }),
).toBeVisible();
await expect(
page.getByRole("button", { name: "Show Previous Events" }),
).toBeVisible();

const table = page.getByTestId("events-table");
await expect(table).toBeVisible();

const rows = await table.locator("tbody tr").all();
const expectedTableData = await getUpcomingEvents();

for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const expectedData = expectedTableData[i];
const title = await row.locator("td:nth-child(1)").innerText();
const location = await row.locator("td:nth-child(4)").innerText();
const description = await row.locator("td:nth-child(5)").innerText();
const host = await row.locator("td:nth-child(6)").innerText();
const featured = await row.locator("td:nth-child(7)").innerText();
const repeats = await row.locator("td:nth-child(8)").innerText();

expect(title).toEqual(expectedData.title);
expect(location).toEqual(expectedData.location);
expect(description).toEqual(expectedData.description);
expect(host).toEqual(expectedData.host);
expect(featured).toEqual(expectedData.featured ? "Yes" : "No");
expect(repeats).toEqual(capitalizeFirstLetter(expectedData.repeats));
}

expect(page.url()).toEqual("https://manage.qa.acmuiuc.org/events/manage");
});
});
34 changes: 34 additions & 0 deletions tests/e2e/login.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { expect } from "@playwright/test";
import { test } from "./base";
import { describe } from "node:test";

describe("Login tests", () => {
test("A user can login and view the home screen", async ({
page,
becomeUser,
}) => {
await becomeUser(page);
await expect(
page.locator("a").filter({ hasText: "Management Portal DEV ENV" }),
).toBeVisible();
await expect(page.locator("a").filter({ hasText: "Events" })).toBeVisible();
await expect(
page.locator("a").filter({ hasText: "Ticketing/Merch" }),
).toBeVisible();
await expect(page.locator("a").filter({ hasText: "IAM" })).toBeVisible();
await expect(
page.getByRole("link", { name: "ACM Logo Management Portal" }),
).toBeVisible();
await expect(
page.getByRole("link", { name: "P", exact: true }),
).toBeVisible();
await page.getByRole("link", { name: "P", exact: true }).click();
await expect(page.getByLabel("PMy Account")).toContainText(
"Name Playwright Core User",
);
await expect(page.getByLabel("PMy Account")).toContainText(
"Emailcore-e2e-testing@acm.illinois.edu",
);
expect(page.url()).toEqual("https://manage.qa.acmuiuc.org/home");
});
});
Loading