Skip to content

Commit

Permalink
feat: add get paid course e2e test
Browse files Browse the repository at this point in the history
  • Loading branch information
typeWolffo committed Oct 17, 2024
1 parent dc0de18 commit cee1395
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 63 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/nighty-playwright.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# uncomment when staging will be ready

# name: Nightly Playwright Tests

# env:
# HUSKY: 0
# HUSKY: 0

# on:
# schedule:
# - cron: "0 1 * * *"
# - cron: "0 6 * * *"
# workflow_dispatch:

# jobs:
Expand Down
86 changes: 86 additions & 0 deletions apps/api/src/e2e-data-seeds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { faker } from "@faker-js/faker";
import { CourseData } from "./utils/types/test-types";

export const e2eCourses: CourseData[] = [
{
title: "For E2E Testing",
description: "DO NOT DELETE THIS COURSE",
state: "published",
priceInCents: 9900,
category: "E2E Testing",
imageUrl: faker.image.urlPicsumPhotos(),
lessons: [
{
title: "E2E Testing Lesson",
description: "E2E Testing Lesson Description",
state: "published",
items: [
{
type: "text_block",
title: "E2E Testing Text Block",
body: "E2E Testing Text Block Body",
state: "published",
},
{
type: "question",
questionType: "open_answer",
questionBody: "E2E Testing Question Body",
state: "published",
},
],
},
{
title: "E2E Testing Lesson 2",
description: "E2E Testing Lesson 2 Description",
state: "published",
items: [
{
type: "text_block",
title: "E2E Testing Text Block 2",
body: "E2E Testing Text Block 2 Body",
state: "published",
},
{
type: "file",
title: "E2E Testing File",
fileType: "external_video",
url: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4",
state: "published",
},
{
type: "question",
questionType: "single_choice",
questionBody: "E2E Testing Single Choice Question Body",
state: "published",
},
],
},
{
title: "E2E Testing Lesson 3",
description: "E2E Testing Lesson 3 Description",
state: "published",
items: [
{
type: "text_block",
title: "E2E Testing Text Block 3",
body: "E2E Testing Text Block 3 Body",
state: "published",
},
{
type: "file",
title: "E2E Testing File 2",
fileType: "external_presentation",
url: "https://res.cloudinary.com/dinpapxzv/raw/upload/v1727104719/presentation_gp0o3d.pptx",
state: "published",
},
{
type: "question",
questionType: "multiple_choice",
questionBody: "E2E Testing Multiple Choice Question Body",
state: "published",
},
],
},
],
},
];
52 changes: 2 additions & 50 deletions apps/api/src/nice-data-seeds.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,7 @@
import { faker } from "@faker-js/faker";
import { Status } from "./storage/schema/utils";
import { CourseData } from "./utils/types/test-types";

export const LessonFileType = {
presentation: "Presentation",
external_presentation: "External Presentation",
video: "Video",
external_video: "External Video",
} as const;

export const QuestionType = {
open_answer: "Open Answer",
single_choice: "Single Choice",
multiple_choice: "Multiple Choice",
} as const;

export interface NiceCourseData {
title: string;
description: string;
imageUrl?: string;
state: keyof typeof Status;
priceInCents: number;
category: string;
lessons: {
title: string;
description: string;
state: keyof typeof Status;
items: Array<
| {
type: "text_block";
title: string;
body: string;
state: keyof typeof Status;
}
| {
type: "file";
title: string;
fileType: keyof typeof LessonFileType;
url: string;
state: keyof typeof Status;
}
| {
type: "question";
questionType: keyof typeof QuestionType;
questionBody: string;
state: keyof typeof Status;
}
>;
}[];
}

export const niceCourses: NiceCourseData[] = [
export const niceCourses: CourseData[] = [
{
title: "Foundations of Accounting: Principles and Practices",
description:
Expand Down
14 changes: 9 additions & 5 deletions apps/api/src/seed-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { faker } from "@faker-js/faker";
import { sql } from "drizzle-orm/sql";
import {
categories,
courseLessons,
Expand All @@ -11,11 +12,14 @@ import {
textBlocks,
} from "src/storage/schema";
import { DatabasePg } from "./common";
import { niceCourses } from "./nice-data-seeds";
import { sql } from "drizzle-orm/sql";

export async function createNiceCourses(adminUserId: string, db: DatabasePg) {
for (const courseData of niceCourses) {
import { CourseData } from "./utils/types/test-types";

export async function createNiceCourses(
adminUserId: string,
db: DatabasePg,
data: CourseData[],
) {
for (const courseData of data) {
const [category] = await db
.insert(categories)
.values({
Expand Down
6 changes: 5 additions & 1 deletion apps/api/src/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
import { createNiceCourses, seedTruncateAllTables } from "./seed-helpers";
import { DatabasePg } from "./common";
import hashPassword from "./common/helpers/hashPassword";
import { niceCourses } from "./nice-data-seeds";
import { e2eCourses } from "./e2e-data-seeds";

dotenv.config({ path: "./.env" });

Expand Down Expand Up @@ -177,8 +179,10 @@ async function seed() {
await createUsers(5);
console.log("Created users with credentials");

await createNiceCourses(adminUser.id, db);
await createNiceCourses(adminUser.id, db, niceCourses);
console.log("✨✨✨Created created nice courses✨✨✨");
await createNiceCourses(adminUser.id, db, e2eCourses);
console.log("🧪 Created e2e courses");

const createdCategories = await createEntities(categories, 6, () => ({
id: faker.string.uuid(),
Expand Down
49 changes: 49 additions & 0 deletions apps/api/src/utils/types/test-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Status } from "src/storage/schema/utils";

export const LessonFileType = {
presentation: "Presentation",
external_presentation: "External Presentation",
video: "Video",
external_video: "External Video",
} as const;

export const QuestionType = {
open_answer: "Open Answer",
single_choice: "Single Choice",
multiple_choice: "Multiple Choice",
} as const;

export interface CourseData {
title: string;
description: string;
imageUrl?: string;
state: keyof typeof Status;
priceInCents: number;
category: string;
lessons: {
title: string;
description: string;
state: keyof typeof Status;
items: Array<
| {
type: "text_block";
title: string;
body: string;
state: keyof typeof Status;
}
| {
type: "file";
title: string;
fileType: keyof typeof LessonFileType;
url: string;
state: keyof typeof Status;
}
| {
type: "question";
questionType: keyof typeof QuestionType;
questionBody: string;
state: keyof typeof Status;
}
>;
}[];
}
1 change: 1 addition & 0 deletions apps/web/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_modules
/build
.env
/test-results
**/e2e/.auth
56 changes: 56 additions & 0 deletions apps/web/e2e/tests/get-course.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { expect, test } from "@playwright/test";

test.describe("course", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/auth/login");
});

test("should find, open and enroll the paid course", async ({ page }) => {
await page.getByLabel("email").fill("[email protected]");
await page.getByLabel("password").fill("studentpassword");
await page.getByRole("button", { name: /login/i }).click();

await expect(page).toHaveURL("/");
await expect(page).toHaveTitle(/dashboard/i);

await page
.getByPlaceholder("Search by name or keyword...")
.fill("For E2E Testing");
await expect(page.getByRole("button", { name: "Clear All" })).toBeVisible();

await page.getByRole("link", { name: "For E2E Testing" }).click();
await expect(page).toHaveURL(
/course\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/
);
await expect(page.getByText("For E2E Testing")).toBeVisible();
await expect(
page.getByText("E2E Testing Lesson Description")
).toBeVisible();
await expect(
page.getByText("E2E Testing Lesson 2 Description")
).toBeVisible();
await expect(
page.getByText("E2E Testing Lesson 3 Description")
).toBeVisible();

await page.getByRole("button", { name: "Enroll" }).click();

const stripeFrame = page.frameLocator(
'iframe[title="Secure payment input frame"]'
);
await stripeFrame.locator("#Field-numberInput").fill("4242424242424242");
await stripeFrame
.locator("#Field-expiryInput")
.fill(`10${new Date().getFullYear() + 1}`);
await stripeFrame.locator("#Field-cvcInput").fill("123");
await expect(page.getByText(/Buy for/)).toBeVisible();

await page.getByRole("button", { name: /Buy for/ }).click();

const unenrollButton = page.getByRole("button", { name: "Unenroll" });
await unenrollButton.waitFor({ state: "visible", timeout: 10000 });
await expect(unenrollButton).toBeVisible();
await unenrollButton.click();
await expect(page.getByRole("button", { name: /Enroll - / })).toBeVisible();
});
});
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ test.describe("register page", () => {
});

test("register user", async ({ page }) => {
await page.getByLabel("first name").fill("testname");
await page.getByLabel("last name").fill("testlastname");
await page.getByLabel("email").fill("[email protected]");
await page.getByLabel("password").fill("password");

Expand Down
15 changes: 12 additions & 3 deletions apps/web/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default defineConfig({
workers: process.env.CI ? 1 : undefined,
use: {
baseURL: process.env.CI
? "https://staging-url.example.com"
? "https://lms.beta.selleo.app"
: "https://app.lms.localhost",
ignoreHTTPSErrors: true,
// launchOptions: {
Expand All @@ -24,13 +24,22 @@ export default defineConfig({
},

projects: [
{ name: "setup", testMatch: /.*\.setup\.ts/ },
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
use: {
...devices["Desktop Chrome"],
// storageState: "e2e/.auth/user.json",
},
// dependencies: ["setup"],
},
{
name: "firefox",
use: { ...devices["Desktop Firefox"] },
use: {
...devices["Desktop Firefox"],
// storageState: "e2e/.auth/user.json",
},
// dependencies: ["setup"],
},
],
});

0 comments on commit cee1395

Please sign in to comment.