Files
open-saas/template/e2e-tests/tests/demoAppTests.spec.ts
Franjo Mindek a55adf7eb9 for now
2025-11-06 13:45:40 +01:00

140 lines
4.6 KiB
TypeScript

import { expect, test, type Page } from "@playwright/test";
import {
createRandomUser,
logUserIn,
makeStripePayment,
signUserUp,
type User,
} from "./utils";
let page: Page;
let testUser: User;
/**
* Each user is given 3 credits for free on signup. This will allow them to call the OpenAI API 3 times.
* After that, if they haven't paid, they will not be able to generate a schedule.
* In this test file, we run all tests sequentially so that we use up the user's first 3 credits
* and the 4th generation should fail. We can then test stripe payments and the ability to generate a schedule after payment.
*/
test.describe.configure({ mode: "serial" });
test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
testUser = createRandomUser();
await signUserUp({ page, user: testUser });
await logUserIn({ page, user: testUser });
});
test.afterAll(async () => {
await page.close();
});
const task1 = "Create presentation on SaaS";
const task2 = "Build SaaS app draft";
test("User can make 3 AI schedule generations", async () => {
test.slow(); // Use a longer timeout time in case OpenAI is slow to respond
expect(page.url()).toContain("/demo-app");
await page.fill('input[id="description"]', task1);
await page.click('button:has-text("Add task")');
await expect(page.getByText(task1)).toBeVisible();
await page.fill('input[id="description"]', task2);
await page.click('button:has-text("Add task")');
await expect(page.getByText(task2)).toBeVisible();
for (let i = 0; i < 3; i++) {
const generateScheduleButton = page.getByTestId("generate-schedule-button");
await expect(generateScheduleButton).toBeVisible();
await Promise.all([
page.waitForRequest(
(req) =>
req.url().includes("operations/generate-gpt-response") &&
req.method() === "POST",
),
page.waitForResponse((response) => {
return (
response.url().includes("/operations/generate-gpt-response") &&
response.status() === 200
);
}),
// We already started waiting before we perform the click that triggers the API calls. So now we just perform the click
generateScheduleButton.click(),
]);
const schedule = page.getByTestId("schedule");
expect(schedule).toContainText(task1, { ignoreCase: true });
expect(schedule).toContainText(task2, { ignoreCase: true });
}
});
test("AI schedule generation fails on 4th attempt", async () => {
test.slow(); // Use a longer timeout time in case OpenAI is slow to respond
await page.reload();
const generateScheduleButton = page.getByTestId("generate-schedule-button");
await expect(generateScheduleButton).toBeVisible();
await Promise.all([
page.waitForRequest(
(req) =>
req.url().includes("operations/generate-gpt-response") &&
req.method() === "POST",
),
page.waitForResponse((response) => {
// expect the response to be 402 "PAYMENT_REQUIRED"
return (
response.url().includes("/operations/generate-gpt-response") &&
response.status() === 402
);
}),
// We already started waiting before we perform the click that triggers the API calls. So now we just perform the click
generateScheduleButton.click(),
]);
const schedule = page.getByTestId("schedule");
expect(schedule).not.toContainText(task1, { ignoreCase: true });
expect(schedule).not.toContainText(task2, { ignoreCase: true });
});
test("Make test payment with Stripe for hobby plan", async () => {
const planId = "hobby";
await makeStripePayment({ test, page, planId });
});
test("User should be able to generate another schedule after payment", async () => {
await page.goto("/demo-app");
const generateScheduleButton = page.getByTestId("generate-schedule-button");
await expect(generateScheduleButton).toBeVisible();
await Promise.all([
page
.waitForRequest(
(req) =>
req.url().includes("operations/generate-gpt-response") &&
req.method() === "POST",
)
.catch((err) => console.error(err.message)),
page
.waitForResponse((response) => {
if (
response.url().includes("/operations/generate-gpt-response") &&
response.status() === 200
) {
return true;
}
return false;
})
.catch((err) => console.error(err.message)),
// We already started waiting before we perform the click that triggers the API calls. So now we just perform the click
generateScheduleButton.click(),
]);
const schedule = page.getByTestId("schedule");
expect(schedule).toContainText(task1, { ignoreCase: true });
expect(schedule).toContainText(task2, { ignoreCase: true });
});