Skip to content

Commit

Permalink
test demo app
Browse files Browse the repository at this point in the history
  • Loading branch information
vincanger committed Mar 5, 2024
1 parent 0fd85ae commit ce38902
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 93 deletions.
11 changes: 1 addition & 10 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,6 @@ jobs:
ls -la
test -f .env.server && echo ".env.server exists" || echo ".env.server does not exist"
cp .env.server.example .env.server
- name: Commit and push if it's not up-to-date
run: |
git config user.email "github-actions[bot]@users.noreply.github.com"
git config user.name "github-actions[bot]"
cd app
git add -f .env.server
git commit -m "Add .env.server file" -a || echo "No changes to commit"
git push
- name: Set up Playwright
run: |
Expand All @@ -57,4 +48,4 @@ jobs:
- name: Run Playwright tests
run: |
cd app
DEBUG=pw:webserver npx playwright test tests/whatever.spec.ts
DEBUG=pw:webserver npx playwright test
21 changes: 21 additions & 0 deletions app/playwright/tests/landingPageTests.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { test, expect } from '@playwright/test';

test.describe('general landing page tests', () => {
test.beforeEach(async ({ page }) => {
await page.goto('localhost:3000');
});

test('has title', async ({ page }) => {
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle(/SaaS/);
});

test('get started link', async ({ page }) => {
await page.getByRole('link', { name: 'Get started' }).click();
});

test('headings', async ({ page }) => {
expect(page.getByRole('heading', { name: 'SaaS' })).toBeTruthy();
expect(page.getByRole('heading', { name: 'Features' })).toBeTruthy();
});
});
42 changes: 42 additions & 0 deletions app/playwright/tests/paidUserTests.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { expect } from '@playwright/test';
import { createLoggedInUserFixture } from './utils';

// Create a new test fixture with a paid user and a logged in page
const test = createLoggedInUserFixture({ hasPaid: true, credits: 10 });

// test /demo-app page by entering "todo" and clicking add task
test('Demo App: add tasks & generate schedule', async ({ loggedInPage }) => {
expect(loggedInPage.url()).toBe('http://localhost:3000/demo-app');

// Fill input id="description" with "create presentation"
await loggedInPage.fill('input[id="description"]', 'create presentation on SaaS');

// Click button:has-text("Add task")
await loggedInPage.click('button:has-text("Add task")');

await loggedInPage.fill('input[id="description"]', 'build SaaS app draft');

await loggedInPage.click('button:has-text("Add task")');

// expect to find text in a span element
expect(loggedInPage.getByText('create presentation on SaaS')).toBeTruthy();
expect(loggedInPage.getByText('build SaaS app draft')).toBeTruthy();

// find a button with text "Generate Schedule" and check it's visible
const generateScheduleButton = loggedInPage.getByRole('button', { name: 'Generate Schedule' });
expect(generateScheduleButton).toBeTruthy();

await Promise.all([
loggedInPage.waitForRequest(
(req) => req.url().includes('operations/generate-gpt-response') && req.method() === 'POST'
),
loggedInPage.waitForResponse((response) => {
if (response.url() === 'http://localhost:3001/operations/generate-gpt-response' && response.status() === 200) {
return true;
}
return false;
}),
// We already started waiting before we perform the click that triggers the API calls. So now we just perform the click
generateScheduleButton.click(),
]);
});
40 changes: 40 additions & 0 deletions app/playwright/tests/unpaidUserTests.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { expect } from '@playwright/test';
import { createLoggedInUserFixture } from './utils';

// Create a new test fixture with an unpaid user and a logged in page
const test = createLoggedInUserFixture({ hasPaid: false, credits: 0 });

test('Demo app: cannot generate schedule', async ({ loggedInPage }) => {
await loggedInPage.waitForURL('http://localhost:3000/demo-app');

// Fill input id="description" with "create presentation"
await loggedInPage.fill('input[id="description"]', 'create presentation on SaaS');

// Click button:has-text("Add task")
await loggedInPage.click('button:has-text("Add task")');

await loggedInPage.fill('input[id="description"]', 'build SaaS app draft');

await loggedInPage.click('button:has-text("Add task")');

// expect to find text in a span element
expect(loggedInPage.getByText('create presentation on SaaS')).toBeTruthy();
expect(loggedInPage.getByText('build SaaS app draft')).toBeTruthy();

// find a button with text "Generate Schedule" and check it's visible
const generateScheduleButton = loggedInPage.getByRole('button', { name: 'Generate Schedule' });
expect(generateScheduleButton).toBeTruthy();

await Promise.all([
loggedInPage.waitForRequest((req) => req.url().includes('operations/generate-gpt-response') && req.method() === 'POST'),
loggedInPage.waitForResponse((response) => {
// expect the response to be 402 "PAYMENT_REQUIRED"
if (response.url() === 'http://localhost:3001/operations/generate-gpt-response' && response.status() === 402) {
return true;
}
return false;
}),
// We already started waiting before we perform the click that triggers the API calls. So now we just perform the click
generateScheduleButton.click(),
]);
});
78 changes: 78 additions & 0 deletions app/playwright/tests/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { test as base, type Page } from '@playwright/test';
import { PrismaClient } from '@prisma/client';
// Create a new Prisma client to interact with DB
export const prisma = new PrismaClient();

export type User = {
id?: number;
username: string;
password?: string;
hasPaid?: boolean;
credits?: number;
};

export const logUserIn = async ({ page, user }: { page: Page; user: User }) => {
await page.goto('localhost:3000');

// Click the get started link.
await page.getByRole('link', { name: 'Log in' }).click();

console.log('logging in...', user)
await page.waitForURL('http://localhost:3000/login');
console.log('url', page.url());

// Fill input[name="username"]
await page.fill('input[name="username"]', user.username);

// Fill input[name="password"]
await page.fill('input[name="password"]', user.password || 'password123');

// Click button:has-text("Log in")
await page.click('button:has-text("Log in")');
};

export const signUserUp = async ({ page, user }: { page: Page; user: User }) => {
await page.goto('localhost:3000');

// Click the get started link.
await page.getByRole('link', { name: 'Log in' }).click();

// click text "Sign up"
await page.click('text="go to signup"');

// Fill input[name="username"]
await page.fill('input[name="username"]', user.username);

// Fill input[name="password"]
await page.fill('input[name="password"]', user.password || 'password123');

// Click button:has-text("Sign up")
await page.click('button:has-text("Sign up")');
};

export const createRandomUser = () => {
const username = `user${Math.random().toString(36).substring(7)}`;
const password = `password${Math.random().toString(36).substring(7)}!`;

return { username, password };
};

export const createLoggedInUserFixture = ({ hasPaid, credits }: Pick<User, 'hasPaid' | 'credits'>) => base.extend<{ loggedInPage: Page; testUser: User }>({
testUser: async ({}, use) => {
const { username, password } = createRandomUser();
await use({ username, password, hasPaid, credits });
},
loggedInPage: async ({ page, testUser }, use) => {
await signUserUp({ page, user: testUser });
await page.waitForURL('http://localhost:3000/demo-app');
const user = await prisma.user.update({
where: { username: testUser.username },
data: { hasPaid: testUser.hasPaid, credits: testUser.credits },
});
await use(page);
// clean up all that nasty data 🤮
await prisma.gptResponse.deleteMany({ where: { userId: user.id } });
await prisma.task.deleteMany({ where: { userId: user.id } });
await prisma.user.delete({ where: { id: user.id } });
},
});
83 changes: 0 additions & 83 deletions app/playwright/tests/whatever.spec.ts

This file was deleted.

0 comments on commit ce38902

Please sign in to comment.