Skip to content

Commit

Permalink
add(test): add pom draft test for playwright (#55)
Browse files Browse the repository at this point in the history
  • Loading branch information
luisecm authored Jun 28, 2024
1 parent 527d993 commit 0c43ae8
Show file tree
Hide file tree
Showing 8 changed files with 553 additions and 46 deletions.
54 changes: 46 additions & 8 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,62 @@
name: Playwright Tests

on:
schedule:
- cron: "0 0/6 * * 1-5"
pull_request:
types: [opened, synchronize, reopened, edited]
paths-ignore:
- ".github/workflows/**"
- "!.github/workflows/automated-tests.yml"
- "!.github/workflows/playwright.yml"
- ".gitignore"
- ".prettierignore"
- ".prettierrc.json"
- "PULL_REQUEST_TEMPLATE.md"
- "README.md"
workflow_dispatch:

jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Checkout Uplink Web directory 🔖
uses: actions/checkout@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm ci
repository: Satellite-im/UplinkWeb

- name: Checkout Automated Tests directory 🔖
uses: actions/checkout@v4
with:
path: automated-tests

- name: Setup Node.js for Uplink Web 🔨
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies for Uplink Web 📦
run: npm install

- name: Install dependencies for Testing Repo 📦
working-directory: automated-tests
run: npm install

- name: Install Playwright Browsers
working-directory: automated-tests
run: npx playwright install --with-deps

- name: Run server for Uplink Web
run: npm run dev &

- name: Run Playwright tests
working-directory: automated-tests
run: npx playwright test

- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
path: automated-tests/playwright-report/
retention-days: 5
14 changes: 4 additions & 10 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ export default defineConfig({
/* 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. */
timeout: 60000,
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: "http://localhost:5173/",

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
testIdAttribute: "data-cy",
actionTimeout: 20000,
video: "retain-on-failure",
},

/* Configure projects for major browsers */
Expand All @@ -37,16 +41,6 @@ export default defineConfig({
use: { ...devices["Desktop Chrome"] },
},

{
name: "firefox",
use: { ...devices["Desktop Firefox"] },
},

{
name: "webkit",
use: { ...devices["Desktop Safari"] },
},

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
Expand Down
204 changes: 204 additions & 0 deletions playwright/01-pin-input.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import { test, expect } from "@playwright/test";
import { LoginPinPage } from "./PageObjects/LoginPin";
import { faker } from "@faker-js/faker";
import { AuthNewAccount } from "./PageObjects/AuthNewAccount";
import { ChatsMainPage } from "./PageObjects/ChatsMain";

test.describe("Create Account and Login Tests", () => {
const username = faker.internet.userName();
const status = faker.lorem.sentence(3);
const pinNumber = "1234";

test.beforeEach(async ({ page }) => {
const loginPinPage = new LoginPinPage(page);
await loginPinPage.navigateTo();
await loginPinPage.waitUntilPageIsLoaded();
});

test("A1, A9, A11 - Enter valid PIN redirects to Main Page", async ({
page,
}) => {
const loginPinPage = new LoginPinPage(page);
const authNewAccount = new AuthNewAccount(page);
const chatsMainPage = new ChatsMainPage(page);
await loginPinPage.enterPin(pinNumber);
await loginPinPage.pinButtonConfirm.click();
await authNewAccount.validateLoadingHeader();
await page.waitForURL("/auth/new_account");
await expect(authNewAccount.textNewAccountSecondary).toHaveText(
"Let's set up your new account. Please choose a username below.",
);
await expect(authNewAccount.labelNewAccountUsername).toHaveText("Username");
await expect(authNewAccount.labelNewAccountStatus).toHaveText(
"Status Message",
);
await expect(authNewAccount.profilePictureNewAccount).toBeVisible();
await expect(authNewAccount.buttonNewAccountGoBack).toBeVisible();
await expect(authNewAccount.buttonNewAccountCreate).toBeVisible();
await authNewAccount.typeOnUsername(username);
await authNewAccount.typeOnStatus(status);
await authNewAccount.buttonNewAccountCreate.click();
await chatsMainPage.addSomeone.waitFor({ state: "visible" });
await page.waitForURL("/chat");
});

test("A2 - Pin should have at least 4 digits", async ({ page }) => {
const loginPinPage = new LoginPinPage(page);
await loginPinPage.enterPin("123");
await loginPinPage.validateConfirmButtonIsDisabled();
});

test("A3 - Pin cannot have more than 8 digits", async ({ page }) => {
const loginPinPage = new LoginPinPage(page);
await loginPinPage.enterPin("12345678901234");
const count = await loginPinPage.pinDotFilled.count();
expect(count).toEqual(8);
});

test("A4 - Clicking red reset button should erase any inputs made", async ({
page,
}) => {
const loginPinPage = new LoginPinPage(page);
await loginPinPage.enterPin("12345678");
await loginPinPage.buttonClearInput.click();
const count = await loginPinPage.pinDotFilled.count();
expect(count).toEqual(0);
});

test("A5 - Settings dropdown should show option to Scramble numberpad and option to stay unlocked", async ({
page,
}) => {
const loginPinPage = new LoginPinPage(page);
await loginPinPage.goToPinSettings();
await expect(loginPinPage.scrambleKeypadLabel).toBeVisible();
await expect(loginPinPage.scrambleKeypadLabel).toHaveText(
"Scramble keypad?",
);
await expect(loginPinPage.stayUnlockedLabel).toBeVisible();
await expect(loginPinPage.stayUnlockedLabel).toHaveText("Stay unlocked?");
});

test("A6, A7 - Scramble Keypad will change the order of pin input buttons", async ({
page,
}) => {
const loginPinPage = new LoginPinPage(page);
await expect(loginPinPage.pinKeypad).toHaveAttribute(
"data-keyorder",
"1,2,3,4,5,6,7,8,9,0",
);

await loginPinPage.goToPinSettings();
await loginPinPage.clickScrambleKeypadSwitch();

// Validate that the order of the buttons has changed
const newKeyOrder =
await loginPinPage.pinKeypad.getAttribute("data-keyorder");
expect(newKeyOrder).not.toEqual("1,2,3,4,5,6,7,8,9,0");

// Scramble keypad is disabled again by the user
await loginPinPage.clickScrambleKeypadSwitch();
await expect(loginPinPage.pinKeypad).toHaveAttribute(
"data-keyorder",
"1,2,3,4,5,6,7,8,9,0",
);
});

test("A8 - If Stay Unlocked is toggled on, user should bypass PIN page when logging in", async ({
page,
}) => {
const loginPinPage = new LoginPinPage(page);
const authNewAccount = new AuthNewAccount(page);
const chatsMainPage = new ChatsMainPage(page);
await loginPinPage.goToPinSettings();
await loginPinPage.clickStayUnlockedSwitch();
await expect(loginPinPage.stayUnlockedCheckbox).toBeChecked();
await loginPinPage.enterPin(pinNumber);
await loginPinPage.pinButtonConfirm.click();
await authNewAccount.validateLoadingHeader();
await page.waitForURL("/auth/new_account");
await authNewAccount.typeOnUsername(username);
await authNewAccount.typeOnStatus(status);
await authNewAccount.buttonNewAccountCreate.click();
await chatsMainPage.addSomeone.waitFor({ state: "visible" });
await page.waitForURL("/chat");
await chatsMainPage.reloadPage();
await page.waitForURL("/chat");
});

test("A10 - User can see menu to switch to a different profile", async ({
page,
}) => {
const loginPinPage = new LoginPinPage(page);
await loginPinPage.buttonChangeUser.click();
await expect(loginPinPage.selectProfileModal).toBeVisible();
await expect(loginPinPage.selectProfileLabel).toHaveText("Profiles");
await expect(loginPinPage.selectProfileUserName.first()).toHaveText(
"Space Kev",
);
await expect(loginPinPage.selectProfileUserName.last()).toHaveText(
"Sara Saturn",
);
});

test.skip("A12 - If incorrect pin is entered, error message should be displayed", async ({
page,
}) => {
const loginPinPage = new LoginPinPage(page);
const authNewAccount = new AuthNewAccount(page);
const chatsMainPage = new ChatsMainPage(page);
await loginPinPage.goToPinSettings();
await loginPinPage.clickStayUnlockedSwitch();
await loginPinPage.enterPin(pinNumber);
await loginPinPage.pinButtonConfirm.click();
await authNewAccount.validateLoadingHeader();
await authNewAccount.typeOnUsername(username);
await authNewAccount.typeOnStatus(status);
await authNewAccount.buttonNewAccountCreate.click();
await page.waitForURL("/chat");
await chatsMainPage.visitOtherSite("/auth/unlock");
await loginPinPage.enterPin("9876");
await page.keyboard.press("Enter");
await expect(loginPinPage.toastNotification).toBeVisible();
await expect(loginPinPage.toastNotificationText).toHaveText(
"Pin is wrong!",
);
});

test("A13 - If Stay Unlocked is toggled off, user be redirected to enter PIN when refreshing page", async ({
page,
}) => {
const loginPinPage = new LoginPinPage(page);
const authNewAccount = new AuthNewAccount(page);
const chatsMainPage = new ChatsMainPage(page);
await loginPinPage.enterPin(pinNumber);
await loginPinPage.pinButtonConfirm.click();
await authNewAccount.validateLoadingHeader();
await authNewAccount.typeOnUsername(username);
await authNewAccount.typeOnStatus(status);
await authNewAccount.buttonNewAccountCreate.click();
await chatsMainPage.addSomeone.waitFor({ state: "visible" });
await page.waitForURL("/chat");
await chatsMainPage.reloadPage();
await expect(loginPinPage.pinKeypad).toBeVisible();
});

test("A14 - If Stay Unlocked is toggled on, user should be redirected to enter PIN after logging off", async ({
page,
}) => {
const loginPinPage = new LoginPinPage(page);
const authNewAccount = new AuthNewAccount(page);
const chatsMainPage = new ChatsMainPage(page);
await loginPinPage.goToPinSettings();
await loginPinPage.clickStayUnlockedSwitch();
await loginPinPage.enterPin(pinNumber);
await loginPinPage.pinButtonConfirm.click();
await authNewAccount.validateLoadingHeader();
await authNewAccount.typeOnUsername(username);
await authNewAccount.typeOnStatus(status);
await authNewAccount.buttonNewAccountCreate.click();
await chatsMainPage.addSomeone.waitFor({ state: "visible" });
await page.waitForURL("/chat");
await chatsMainPage.goToSettings();
await page.waitForURL("/settings/profile");
});
});
59 changes: 59 additions & 0 deletions playwright/PageObjects/AuthNewAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import MainPage from "./MainPage";
import { expect, type Locator, type Page } from "@playwright/test";

export class AuthNewAccount extends MainPage {
readonly page: Page;
readonly buttonNewAccountGoBack: Locator;
readonly buttonNewAccountCreate: Locator;
readonly titleNewAccount: Locator;
readonly textNewAccountSecondary: Locator;
readonly profilePictureNewAccount: Locator;
readonly labelNewAccountUsername: Locator;
readonly inputNewAccountUsername: Locator;
readonly labelNewAccountStatus: Locator;
readonly inputNewAccountStatus: Locator;

constructor(page: Page) {
super(page);
this.page = page;
this.buttonNewAccountGoBack = page.getByTestId(
"button-new-account-go-back",
);
this.buttonNewAccountCreate = page.getByTestId("button-new-account-create");
this.titleNewAccount = page.getByTestId("title-new-account");
this.textNewAccountSecondary = page.getByTestId(
"text-new-account-secondary",
);
this.profilePictureNewAccount = page.getByTestId(
"profile-picture-new-account",
);
this.labelNewAccountUsername = page.getByTestId(
"label-new-account-username",
);
this.inputNewAccountUsername = page.getByTestId(
"input-new-account-username",
);
this.labelNewAccountStatus = page.getByTestId("label-new-account-status");
this.inputNewAccountStatus = page.getByTestId("input-new-account-status");
}

async createRandomUser(username: string, status: string) {
this.validateLoadingHeader();
this.typeOnUsername(username);
this.typeOnStatus(status);
this.buttonNewAccountCreate.click();
}

async typeOnStatus(status: string) {
await this.inputNewAccountStatus.fill(status);
}

async typeOnUsername(username: string) {
await this.inputNewAccountUsername.fill(username);
}

async validateLoadingHeader() {
await expect(this.titleNewAccount).toBeVisible();
await expect(this.titleNewAccount).toHaveText("Make It Yours");
}
}
Loading

0 comments on commit 0c43ae8

Please sign in to comment.