Feature Tests

Test your installed guestbook against the expected specifications.

The .feature files on this page are Gherkin specifications. npx y2k-guestbook test runs them with Playwright against your installation of the guestbook:

  • A .feature file says what should happen.
  • A step definition is the TypeScript that applies that behaviour in the browser.

Install Playwright

From your Next.js app root:

npm install --save-dev @playwright/test playwright-bdd
npx playwright install chromium

Confirm the package installations by running:

npm ls @playwright/test playwright-bdd

Setup

Test Reports

A test run writes to a Playwright report folder — open index.html inside to view results:

  • A later run will overwrite the previous report.
  • A failed scenario keeps recording in the report you can use to debug.

The default folder is features/reports/results/ — in this setup, we'll use this default folder for user tests.

Support Files

features/support/ contains files that help Playwright run tests by giving them shared context:

features/support/world.ts holds the page, the guestbook URL, and values a later step needs to read:

export class PlaywrightWorld {
  page!: Page;
  baseUrl: string;
  guestbookPath: string;
  adminPath: string;
  postedName?: string;

  constructor() {
    this.baseUrl = String(process.env.BASE_URL ?? "http://localhost:3000").replace(/\/$/, "");
    this.guestbookPath = process.env.NEXT_PUBLIC_GUESTBOOK_PATH || "/";
    this.adminPath = process.env.NEXT_PUBLIC_GUESTBOOK_ADMIN_PATH || "/admin";
  }
}

Step Definitions

Example features/step_definitions/ map each Given / When / Then to clicks in the browser, covering the basic functionality of the guestbook, aligning with the Gherkin .feature files below.

You will need to write step definitions for any additional functionality you opt into (notifications, analytics) or any other features that you add.

Running Tests

Run .feature Tests

These tests do not require any admin authentication, so they can be run without any additional setup.

  1. Start the guestbook preview server: npm run dev

  2. In a second terminal at the app root, call:

    To run a specific test in a feature file, append the --name flag naming a Scenario. For example:

    # Writes to features/reports/results/index.html
    npx y2k-guestbook test features/features/guestbook/guestbook-comments.feature --name "User submits a valid comment"
    

Optional Prefixes

By default, Playwright hides the browser window. To watch a run:

# Headed runs will run in Chrome by default
HEADED=1 npx y2k-guestbook test

Gherkin .feature Files

Poetry Landing Page

Feature: Original Poetry landing navigation (`/`)

    @desktop-nav
    Rule: Hanging bookmarks serve as navigation on desktop

        Background:
            Given a user is on the poetry landing page on desktop

        Scenario: View Docs link works on desktop
            When a user clicks the `view docs` link
            Then a new tab or window opens to the y2k Guestbook Docs

        Scenario: Admin Login link becomes visible on hover on desktop
            When a user hovers over the hidden `admin login` link
            Then the `admin login` link becomes visible

        Scenario: Admin Login link works on desktop
            When a user clicks the `admin login` link
            Then they are directed to the Google SSO page for the admin dashboard

    @mobile-nav
    Rule: Drop-down menu serves as navigation on mobile

        Background:
            Given a user is on the poetry landing page on mobile

        Scenario: View Docs link works on mobile
            When a user clicks the drop-down `menu` button and selects the `view docs` link
            Then a new tab or window opens to the y2k Guestbook Docs

        Scenario: Admin Login link works on mobile
            When a user clicks the drop-down `menu` button and selects the `admin login` link
            Then they are directed to the Google SSO page for the admin dashboard

    @report-issue
    Rule: Report Issue link takes users to the repo Issues page

        Scenario: Report Issue link works on desktop
            Given a user is on the poetry landing page on desktop
            When a user clicks the `report issue` link
            Then a new tab or window opens to `https://github.com/beck-chan/guestbook/issues`

        Scenario: Report Issue link works on mobile
            Given a user is on the poetry landing page on mobile
            When a user clicks the drop-down `menu` button and selects the `report issue` link
            Then a new tab or window opens to `https://github.com/beck-chan/guestbook/issues`

Admin Dashboard

Feature: Unauthorized admin login

    @no-auth-desktop
    Rule: Visitors without admin authorization are denied the dashboard on desktop

        Background:
            Given the user does not have admin authorization
            And a user is on the guestbook page

        Scenario: Unauthorized user is denied the dashboard on desktop
            When a user clicks the `admin login` link
            And they sign in successfully with Google
            Then they are redirected to the landing page
            And they are shown a message that they do not have admin authorization

        Scenario: Unauthorized visitor message can be dismissed on desktop
            Given the user is shown a message that they do not have admin authorization
            When they click the `Boo hiss! Fine.` button
            Then the message closes

    @no-auth-mobile
    Rule: Visitors without admin authorization are denied the dashboard on mobile

        Background:
            Given the user does not have admin authorization
            And a user is on the guestbook page on mobile

        Scenario: Unauthorized user is denied the dashboard on mobile
            When a user clicks the drop-down `menu` button and selects the `admin login` link
            And they sign in successfully with Google
            Then they are redirected to the landing page
            And they are shown a message that they do not have admin authorization

        Scenario: Unauthorized visitor message can be dismissed on mobile
            Given the user is shown a message that they do not have admin authorization
            When they click the `Boo hiss! Fine.` button
            Then the message closes

Write Additional Tests

If a Given / When / Then already has a matching function, Playwright runs that function. A line with no match fails with Missing step: and the text of that line. Create features/step_definitions/your-steps.ts for that line, and import the testing functions:

import { Given, When, Then } from "y2k-guestbook/testing";

Given("your scenario here", async function () {
  await this.page.goto(this.guestbookUrl());
});

Fill in the body with the appropriate code to execute the step. Instruction should be written the way a human user would find things on the page — for example, reference the submit button, the display name field, the prev / next links, and not CSS class names or code.

  • It doesn't matter what the file is called, as long as it's in the features/step_definitions/ directory and has the .ts extension.
  • Stash values you will need later on the World object (for example this.postedName).