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 folder page #1742

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
fee966c
Added tests for most folder logic
MaPoKen Feb 1, 2024
a14a789
Added MyFolder tests
MaPoKen Feb 5, 2024
05cdd68
Added delete/add method
MaPoKen Feb 5, 2024
6c23db6
Merge branch 'master' of https://github.com/NDLANO/ndla-frontend into…
MaPoKen Feb 5, 2024
aebb347
remove repeat 10 times config
MaPoKen Feb 6, 2024
538f22d
Updated e2e and add test
MaPoKen Feb 12, 2024
c8d866f
Merge branch 'master' of github.com:NDLANO/ndla-frontend into e2e-fol…
MaPoKen Mar 4, 2024
6d0da5a
Merge branch 'master' of github.com:NDLANO/ndla-frontend into e2e-fol…
MaPoKen Mar 12, 2024
2d27b76
Updated list of inputs
MaPoKen Mar 12, 2024
56be259
Merge branch 'master' of github.com:NDLANO/ndla-frontend into e2e-fol…
MaPoKen Apr 16, 2024
6378bb0
Add changes from master
MaPoKen Apr 16, 2024
7e66733
Merge branch 'master' of github.com:NDLANO/ndla-frontend into e2e-fol…
MaPoKen Apr 17, 2024
3c53a96
Merged master to resolve flakyness
MaPoKen Apr 17, 2024
cf5229a
Merge branch 'master' of github.com:NDLANO/ndla-frontend into e2e-fol…
MaPoKen May 14, 2024
261633b
Updated myNdlaMenu test
MaPoKen May 14, 2024
285f2c1
Merge branch 'master' of github.com:NDLANO/ndla-frontend into e2e-fol…
MaPoKen May 28, 2024
b8aea2f
Merge branch 'master' of github.com:NDLANO/ndla-frontend into e2e-fol…
MaPoKen May 30, 2024
49dc063
Updated har mocks
MaPoKen May 30, 2024
297eb45
force 1 worker ci
MaPoKen May 30, 2024
60f4f20
Bump playwright
MaPoKen May 30, 2024
4bb34d8
arbitrary changes
MaPoKen May 30, 2024
3e4eff0
Decrease batch interval
MaPoKen May 30, 2024
5eab664
try without batches
MaPoKen May 30, 2024
856a89d
E2E now starts server
MaPoKen May 31, 2024
fb47a3d
Removed unecessary config changes
MaPoKen May 31, 2024
461524d
Merge branch 'master' of github.com:NDLANO/ndla-frontend into e2e-fol…
MaPoKen Jun 26, 2024
007e45b
Removed start server on record
MaPoKen Jun 26, 2024
66c3f9e
Merge branch 'master' of github.com:NDLANO/ndla-frontend into e2e-fol…
MaPoKen Oct 31, 2024
2788f7d
Adjust playwright config for fast runtime
MaPoKen Nov 1, 2024
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
2 changes: 1 addition & 1 deletion e2e/apiMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const test = Ptest.extend<ExtendParams>({
// Creating the API mocking for the wanted API's
await page.routeFromHAR(mockFile(testInfo), {
update: process.env.RECORD_FIXTURES === "true",
updateMode: "minimal",
updateMode: "full",
url: regex,
updateContent: "embed",
});
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

204 changes: 204 additions & 0 deletions e2e/specs/authenticated/MyNDLAFolder.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/**
* Copyright (c) 2024-present, NDLA.
*
* This source code is licensed under the GPLv3 license found in the
* LICENSE file in the root directory of this source tree.
*
*/

import { expect } from "@playwright/test";
import { test, mockWaitResponse } from "../../apiMock";

test.beforeEach(async ({ page }) => {
await page.goto("/minndla/folders");
});

test("can copy sharable link to folder", async ({ page }) => {
await expect(page.getByRole("heading").getByText("Mine mapper")).toBeVisible();
const folderList = page.getByRole("list").filter({ has: page.locator('[data-type="list"]') });
await expect(folderList).toBeVisible();
expect(await folderList.getByRole("listitem").count()).toBeGreaterThanOrEqual(2);

const sharedFolder = folderList
.getByRole("listitem")
.filter({ has: page.getByLabel("Delt Mappe", { exact: true }) })
.nth(1);

const sharedFolderTitle = (await sharedFolder.getByRole("heading").textContent()) ?? "";
await expect(sharedFolder).toBeVisible();

await sharedFolder.getByLabel("Vis redigeringsmuligheter").click();
await page.getByRole("menuitem", { name: "Kopier lenke til mappa", exact: true }).click();

const url: string = await page.evaluate("navigator.clipboard.readText()");
expect(url).toBeDefined();

await page.goto(url);

const heading = page.getByRole("main").getByRole("heading").first();
await expect(heading).toHaveText(sharedFolderTitle);
});

test("change sort order of folders", async ({ page }) => {
const buttons = page.getByTestId("list-view-options").getByRole("button");
const svgs = await buttons.locator("svg").all();

await expect(buttons).toHaveCount(3);
await expect(svgs[0]).toHaveCSS("fill", "rgb(32, 88, 143)");
await expect(page.getByRole("list").filter({ has: page.locator('[data-type="list"]') })).toHaveCount(1);

await buttons.nth(1).click();
await expect(svgs[1]).toHaveCSS("fill", "rgb(32, 88, 143)");
await expect(page.getByRole("list").filter({ has: page.locator('[data-type="listLarger"]') })).toHaveCount(1);

await buttons.nth(2).click();
await expect(svgs[2]).toHaveCSS("fill", "rgb(32, 88, 143)");
await expect(page.getByRole("list").filter({ has: page.locator('[data-type="block"]') })).toHaveCount(1);

await buttons.nth(0).click();
await expect(svgs[0]).toHaveCSS("fill", "rgb(32, 88, 143)");
await expect(page.getByRole("list").filter({ has: page.locator('[data-type="list"]') })).toHaveCount(1);
});

test("can add and delete folder", async ({ page, harCheckpoint }) => {
await expect(page.getByRole("heading").getByText("Mine mapper")).toBeVisible();
const folderList = page.getByRole("list").filter({ has: page.locator('[data-type="list"]') });
await expect(folderList).toBeVisible();
const count = await folderList.getByRole("listitem").count();
expect(count).toBeGreaterThanOrEqual(2);
await page.getByRole("button", { name: "Ny mappe" }).click();
await page.getByLabel("Navn").click();
const name = "Vår sterke test mappe";
await page.keyboard.type(name);

await harCheckpoint();
await page.getByRole("button", { name: "Lagre", exact: true }).click();
await mockWaitResponse(page, "**/graphql-api/graphql");
await expect(page.getByRole("dialog")).not.toBeVisible();
await expect(folderList.getByRole("listitem")).toHaveCount(count + 1);
await page.getByRole("listitem").filter({ hasText: name }).getByLabel("Vis redigeringsmuligheter").click();
await page.getByRole("menuitem", { name: "Slett" }).click();
await harCheckpoint();
await page.getByRole("dialog").getByRole("button", { name: "Slett mappe" }).click();
await mockWaitResponse(page, "**/graphql-api/graphql");
await expect(page.getByRole("dialog")).not.toBeVisible();
await mockWaitResponse(page, "**/graphql-api/graphql");
await expect(page.getByRole("listitem").getByText(name).last()).toBeVisible();
await expect(folderList.getByRole("listitem")).toHaveCount(count);
});

test("can drag and drop folders", async ({ page }) => {
await expect(page.getByRole("heading").getByText("Mine mapper")).toBeVisible();
const folderList = page.getByRole("list").filter({ has: page.locator('[data-type="list"]') });
await expect(folderList).toBeVisible();
expect(await folderList.getByRole("listitem").count()).toBeGreaterThanOrEqual(2);

const initialFolderOrder = await folderList.getByRole("listitem").getByRole("heading").allTextContents();
const firstItem = folderList.getByRole("listitem").first().getByRole("button").first();
const secondItem = folderList.getByRole("listitem").nth(1).getByRole("button").first();

await secondItem.hover();
await page.mouse.down();
await firstItem.hover();
await page.mouse.up();

const newFolderOrder = await folderList.getByRole("listitem").getByRole("heading").allTextContents();

expect(initialFolderOrder).not.toStrictEqual(newFolderOrder);

await secondItem.hover();
await page.mouse.down();
await firstItem.hover();
await page.mouse.up();

const oldFolderOrder = await folderList.getByRole("listitem").getByRole("heading").allTextContents();

expect(initialFolderOrder).toStrictEqual(oldFolderOrder);
});

test("can share and unshare folder", async ({ page }) => {
await expect(page.getByRole("heading").getByText("Mine mapper")).toBeVisible();
const folderList = page.getByRole("list").filter({ has: page.locator('[data-type="list"]') });
await expect(folderList).toBeVisible();
expect(await folderList.getByRole("listitem").count()).toBeGreaterThanOrEqual(2);

const unSharedFolder = folderList
.getByRole("listitem")
.filter({ hasNot: page.getByLabel("Delt mappe") })
.first();
const sharedFolderTitle = (await unSharedFolder.getByRole("heading").textContent()) ?? "";
expect(unSharedFolder).toBeVisible();

await unSharedFolder.getByRole("button").nth(1).click();
await page.getByRole("menuitem", { name: "Del", exact: true }).click();

await page.getByRole("dialog").getByRole("button", { name: "Ferdig" }).click();
expect(
await folderList
.getByRole("listitem")
.filter({
has: page.getByLabel("Delt mappe"),
hasText: sharedFolderTitle,
})
.getByRole("heading")
.textContent(),
).toStrictEqual(sharedFolderTitle);

await page
.getByRole("listitem")
.filter({
hasText: sharedFolderTitle,
})
.getByRole("button")
.nth(1)
.click();

await page.getByRole("menuitem", { name: "Avslutt deling", exact: true }).click();

expect(
await folderList
.getByRole("listitem")
.filter({
hasNot: page.getByLabel("Delt mappe"),
hasText: sharedFolderTitle,
})
.getByRole("heading")
.textContent(),
).toStrictEqual(sharedFolderTitle);
});

test("can go to shared folder page", async ({ page }) => {
await expect(page.getByRole("heading").getByText("Mine mapper")).toBeVisible();
const folderList = page.getByRole("list").filter({ has: page.locator('[data-type="list"]') });
await expect(folderList).toBeVisible();
expect(await folderList.getByRole("listitem").count()).toBeGreaterThanOrEqual(2);
const sharedFolder = folderList
.getByRole("listitem")
.filter({ has: page.getByLabel("Delt Mappe", { exact: true }) })
.nth(1);

const sharedFolderTitle = (await sharedFolder.getByRole("heading").textContent()) ?? "";
expect(sharedFolder).toBeDefined();

await sharedFolder.getByRole("button").nth(1).click();
await page.getByRole("menuitem", { name: "Gå til delt mappe", exact: true }).click();

await page.waitForURL("/folder/*");

await expect(page.getByRole("main").getByRole("heading")).toHaveText(sharedFolderTitle);
});

test("can edit folder name on list item ", async ({ page, harCheckpoint }) => {
await expect(page.getByRole("heading").getByText("Mine mapper")).toBeVisible();

const folderList = page.getByRole("list").filter({ has: page.locator('[data-type="list"]') });
await expect(folderList).toBeVisible();
expect(await folderList.getByRole("listitem").count()).toBeGreaterThanOrEqual(1);
await folderList.first().getByRole("button").nth(1).click();

await harCheckpoint();
await page.getByRole("menuitem", { name: "Rediger" }).click();
await page.getByLabel("Navn").click();
await page.keyboard.press("Control+a");
await page.keyboard.type([...Array(5)].map(() => Math.random().toString(36)[2]).join(""));
});
1 change: 1 addition & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default defineConfig({
testMatch: "e2e/specs/authenticated/*.spec.ts",
dependencies: ["setup"],
use: {
permissions: ["clipboard-read", "clipboard-write"],
storageState: STORAGE_STATE,
},
},
Expand Down
2 changes: 1 addition & 1 deletion src/containers/MyNdla/Folders/ListViewOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ interface Props {
const ListViewOptions = ({ onTypeChange, type }: Props) => {
const { t } = useTranslation();
return (
<StyledDisplayOptionsContainer>
<StyledDisplayOptionsContainer data-testid="list-view-options">
<Tooltip tooltip={t("myNdla.listView")}>
<StyledIconButton
selected={type === "list"}
Expand Down
Loading