Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

E2e tests #58

Merged
merged 12 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,34 @@ jobs:
- run: npm run lint
- run: npm run ts:check
- run: npm run build

- name: Cache build folder
id: cache-build
uses: actions/cache/save@v3
with:
path: ${{ github.workspace }}/build
key: ${{ github.sha }}-build
tests:
runs-on: ubuntu-latest
needs:
- build
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/cache/restore@v3
id: restore-build
with:
path: ${{ github.workspace }}/build
key: ${{ github.sha }}-build
- uses: actions/setup-node@v3
with:
node-version: 20
- run: npm i
- run: npx playwright install --with-deps
- run: npx playwright test
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ android/app/build
android/.gradle
android/app-release-*
android/*.keystore
android/.idea
android/.idea

# Playwright
/test-results/
/playwright-report/
/playwright/.cache/
/screenshots
18 changes: 18 additions & 0 deletions e2e/colorScheme.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { expect, test } from "@playwright/test";

test("colorscheme interface", async ({ page }) => {
await page.goto("localhost:3000");

await expect(
page.locator("html[data-mantine-color-scheme=light]"),
).toBeVisible();

await page.getByRole("button", { name: "Toggle color scheme" }).click();

await expect(
page.locator("html[data-mantine-color-scheme=light]"),
).not.toBeVisible();
await expect(
page.locator("html[data-mantine-color-scheme=dark]"),
).toBeVisible();
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions e2e/dashboard.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { expect, test } from "@playwright/test";

test("default blocks are visible", async ({ page }) => {
await page.goto("localhost:3000");

await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
await expect(page.getByTestId("recently-play-empty")).toBeVisible();
await expect(page.getByTestId("recent-favorites")).toBeVisible();
await expect(
page.getByRole("list", { name: "Moods & genres" }).getByRole("listitem"),
).toHaveCount(113);
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 60 additions & 0 deletions e2e/favorites.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { expect, test } from "@playwright/test";

import { navigateTo, selectedInstance } from "./utils";

test("save card in favorites", async ({ page }) => {
await page.goto("localhost:3000");
await selectedInstance(page, "invidious.fdn.fr");

// Go to Trending page
await page.getByRole("button", { name: "Trending" }).click();
await expect(page.getByRole("heading", { name: "Trending" })).toBeVisible();
await expect(page.getByRole("list", { name: "Trending" })).toBeVisible();

// Toggle favorite button
await page.getByRole("button", { name: "Add to favorite" }).first().click();
await expect(
page.getByRole("button", { name: "Remove from favorite" }),
).toBeVisible();

// Verify notification visibility
await expect(page.getByRole("alert")).toContainText(/Added to favorites/);

// Go to Favorites page
await navigateTo(page, "Favorites", "Favorites");

// Check tab navigation
await expect(page.getByRole("tablist").getByRole("tab")).toHaveCount(5);
// Check default tab is All
await expect(
page.getByRole("tablist").getByRole("tab", {
selected: true,
}),
).toContainText(/All/);

// Check data-list
await expect(
page.getByRole("list", { name: "Favorites list" }).getByRole("listitem"),
).toHaveCount(1);
await expect(
page.getByRole("button", { name: "Remove from favorite" }),
).toBeVisible();

// Switch tab to Videos
await page.getByRole("tablist").getByRole("tab", { name: "Videos" }).click();
await expect(
page.getByRole("tablist").getByRole("tab", {
selected: true,
}),
).toContainText(/Videos/);

// Check data-list displayed
await expect(
page
.getByRole("list", { name: "Favorites videos list" })
.getByRole("listitem"),
).toHaveCount(1);
await expect(
page.getByRole("button", { name: "Remove from favorite" }),
).toBeVisible();
});
33 changes: 33 additions & 0 deletions e2e/player.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { expect, test } from "@playwright/test";

import { search, selectedInstance } from "./utils";

test.describe.serial("player", () => {
test.skip("play video", async ({ page }) => {
await page.goto("localhost:3000");

await selectedInstance(page, "invidious.fdn.fr");

await page.reload();

await search(page, "Eminem lyric");

await page
.getByRole("list", { name: "Search result list Eminem lyric" })
.getByRole("listitem")
.first()
.click();

await expect(page.getByRole("dialog", { name: "Player" })).toBeVisible({
timeout: 15000,
});

// Ne fonctionne pas

await expect(
page.getByRole("status", { name: "Player loading" }),
).toBeVisible({
timeout: 15000,
});
});
});
217 changes: 217 additions & 0 deletions e2e/playlists.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import { expect, test } from "@playwright/test";

import {
checkNotification,
navigateTo,
search,
selectSearchType,
selectedInstance,
} from "./utils";

const createPlaylist = async (page, title: string) => {
await selectedInstance(page, "invidious.fdn.fr");
await navigateTo(page, "Playlists", "Playlists");

// Open modal to create playlist
await page
.getByRole("button", { name: "Open modal to create playlist" })
.click();

// Fill form to create playlist
await page
.getByRole("form", { name: "Form create playlist" })
.getByPlaceholder("My awesome title")
.fill(title);
await page
.getByRole("form", { name: "Form create playlist" })
.getByRole("button", { name: "Create playlist" })
.click();

// Verify notification visibility
await checkNotification(page, /has been created/);
};

test.describe.serial("playlists", () => {
test("create playlist and add video", async ({ page }) => {
await page.goto("localhost:3000");
await createPlaylist(page, "My first playlist");

// Check some elements on the playlist card
await expect(
page.getByRole("heading", { name: "My first playlist" }),
).toBeVisible();
await expect(page.getByRole("listitem")).toContainText("0 videos");

// Go to playlist detail
await page.getByRole("heading", { name: "My first playlist" }).click();
await expect(
page.getByRole("heading", { name: "My first playlist" }),
).toBeVisible();
await expect(page.getByRole("alert")).toContainText(
/My first playlist is empty/,
);

// Go back to playlists
await page.getByRole("button", { name: "Back to previous page" }).click();
await expect(
page.getByRole("heading", { name: "Playlists" }),
).toBeVisible();

// Go to trending and wait for the list to be visible
await navigateTo(page, "Trending", "Trending");
await expect(page.getByRole("list", { name: "Trending" })).toBeVisible({
timeout: 10000,
});

await page
.getByRole("listitem")
.first()
.getByRole("button", { name: "Card menu" })
.click();

await expect(page.getByRole("menu")).toBeVisible();
await page
.getByRole("menu")
.getByRole("menuitem", { name: "Add to playlist" })
.click();

await expect(
page.getByRole("form", { name: "Form add to playlist" }),
).toBeVisible();
await expect(
page
.getByRole("form", { name: "Form add to playlist" })
.getByRole("button", { name: "Add to playlist" }),
).not.toBeEnabled();
await page
.getByRole("form", { name: "Form add to playlist" })
.getByPlaceholder("Your playlist")
.click();
await page.locator('[value="My first playlist"]').click();
await expect(
page
.getByRole("form", { name: "Form add to playlist" })
.getByRole("button", { name: "Add to playlist" }),
).toBeEnabled();
await page
.getByRole("form", { name: "Form add to playlist" })
.getByRole("button", { name: "Add to playlist" })
.click();

// Verify notification visibility
await checkNotification(page, /Added to playlist/);

// Go to playlists
await navigateTo(page, "Playlists", "Playlists");

await expect(page.getByRole("listitem")).toContainText("1 videos");

// Save remote playlist to user playlists
await selectSearchType(page, "playlist");
await search(page, "Tomorrowland 2018");

await page
.getByRole("list", { name: "Search result list Tomorrowland 2018" })
.getByRole("listitem")
.first()
.getByRole("button", {
name: "Save to playlists",
})
.click();

await checkNotification(page, /added to your playlists list/);

await page
.getByRole("list", { name: "Search result list Tomorrowland 2018" })
.getByRole("listitem")
.nth(3)
.getByRole("button", {
name: "Save to playlists",
})
.click();

await checkNotification(page, /added to your playlists list/);

await navigateTo(page, "Playlists", "Playlists");

await page.reload();

// Check persisted data
await expect(
page.getByRole("heading", { name: "Playlists" }),
).toBeVisible();
await expect(
page.getByRole("list", { name: "Playlists list" }).getByRole("listitem"),
).toHaveCount(3);
});

test("edit playlist", async ({ page }) => {
await page.goto("localhost:3000");
await createPlaylist(page, "Awesome playlist");

// Open playlist menu
await page.getByRole("button", { name: "Open playlist menu" }).click();
await page
.getByRole("menu")
.getByRole("menuitem", { name: "Edit" })
.click();

await expect(
page.getByRole("form", { name: "Form update playlist" }),
).toBeVisible();
await page
.getByRole("form", { name: "Form update playlist" })
.getByPlaceholder("My awesome title")
.fill("Awesome playlist updated");
await page
.getByRole("form", { name: "Form update playlist" })
.getByRole("button", { name: "Update playlist" })
.click();

// Verify notification visibility
await checkNotification(page, /Awesome playlist updated has been updated/);

await page.reload();

// Check persisted data
await expect(
page.getByRole("heading", { name: "Playlists" }),
).toBeVisible();
await expect(
page.getByRole("list", { name: "Playlists list" }).getByRole("listitem"),
).toHaveCount(1);
await expect(
page
.getByRole("listitem")
.getByRole("heading", { name: "Awesome playlist updated" }),
).toBeVisible();
});

test("remove playlist", async ({ page }) => {
await page.goto("localhost:3000");
await createPlaylist(page, "Awesome playlist");

// Open playlist menu
await page.getByRole("button", { name: "Open playlist menu" }).click();
await page
.getByRole("menu")
.getByRole("menuitem", { name: "Delete" })
.click();

await expect(
page.getByRole("form", { name: "Delete playlist" }),
).toBeVisible();
await expect(
page.getByRole("form", { name: "Delete playlist" }),
).toContainText(/Do you want deleted Awesome playlist playlist ?/);
await page
.getByRole("form", { name: "Delete playlist" })
.getByRole("button", { name: "Delete playlist" })
.click();

await expect(page.getByTestId("playlists-empty")).toBeVisible();
await expect(page.getByTestId("playlists-empty")).toContainText(
/You have no playlist/,
);
});
});
Loading