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

#8428: playwright activating a quick bar mod when you dont have a quick bar shortcut configured #8429

Merged
Show file tree
Hide file tree
Changes from 3 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
10 changes: 10 additions & 0 deletions end-to-end-tests/pageObjects/extensionConsole/modsPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,16 @@ export class ActivateModPage {
return this.page.getByRole("button", { name: "Activate" });
}

configureQuickbarShortcutLink() {
return this.page.getByRole("link", { name: "configured your Quick Bar" });
}

keyboardShortcutDocumentationLink() {
return this.page.getByRole("link", {
name: "configuring keyboard shortcuts",
});
}

/** Successfully activating the mod will navigate to the "All Mods" page. */
async clickActivateAndWaitForModsPageRedirect() {
await this.activateButton().click();
Expand Down
138 changes: 138 additions & 0 deletions end-to-end-tests/pageObjects/extensionsShortcutsPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* Copyright (C) 2024 PixieBrix, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { expect, type Page } from "@playwright/test";
import { getModifierKey, getModifierSymbol } from "end-to-end-tests/utils";

export class ExtensionsShortcutsPage {
private readonly pageUrl: string;

constructor(
private readonly page: Page,
private readonly chromiumChannel: "chrome" | "msedge",
) {
this.pageUrl =
chromiumChannel === "chrome"
? "chrome://extensions/shortcuts"
: "edge://extensions/shortcuts";
grahamlangford marked this conversation as resolved.
Show resolved Hide resolved
}

getPageUrl() {
return this.pageUrl;
}

async goto() {
await this.page.goto(this.pageUrl);

if (this.chromiumChannel === "chrome") {
await expect(
this.page.getByRole("heading", { name: "PixieBrix - Development" }),
).toBeVisible();
} else {
await expect(
this.page.getByText("PixieBrix - Development"),
).toBeVisible();
}
}

async clearShortcut() {
grahamlangford marked this conversation as resolved.
Show resolved Hide resolved
const modifierSymbol = await getModifierSymbol(this.page);
const shortcut = `${modifierSymbol}M`;

if (this.chromiumChannel === "chrome") {
await expect(
this.page.getByPlaceholder(`Shortcut set: ${shortcut}`),
).toHaveValue(shortcut);

await this.page.getByLabel("Edit shortcut Toggle Quick").click();
grahamlangford marked this conversation as resolved.
Show resolved Hide resolved
await this.page
.locator("extensions-keyboard-shortcuts #container")
.click();

await expect(
this.page.getByLabel(
"Shortcut Toggle Quick Bar for PixieBrix - Development",
{
exact: true,
},
),
).toBeEmpty();
} else {
await expect(
this.page.getByLabel(
"Type a shortcut that will Toggle Quick Bar for PixieBrix - Development extension",
),
).toHaveValue(shortcut);

await this.page.getByRole("button", { name: "Clear shortcut" }).click();

await expect(
this.page.getByLabel(
"Type a shortcut that will Toggle Quick Bar for PixieBrix - Development extension",
),
).toBeEmpty();
}
}

async setShortcut() {
grahamlangford marked this conversation as resolved.
Show resolved Hide resolved
const modifierKey = await getModifierKey(this.page);

const modifierSymbol = await getModifierSymbol(this.page);
const shortcut = `${modifierSymbol}M`;

if (this.chromiumChannel === "chrome") {
await expect(
this.page.getByLabel(
"Shortcut Toggle Quick Bar for PixieBrix - Development",
{
exact: true,
},
),
).toBeEmpty();

await this.page.getByLabel("Edit shortcut Toggle Quick").click();
await this.page
.getByPlaceholder("Type a shortcut")
.press(`${modifierKey}+m`);

await this.page
.locator("extensions-keyboard-shortcuts #container")
.click();

await expect(
this.page.getByPlaceholder(
`Shortcut set: ${
modifierKey === "Meta" ? "Command" : modifierKey
} + M`,
),
).toHaveValue(shortcut);
} else {
const input = this.page.getByLabel(
"Type a shortcut that will Toggle Quick Bar for PixieBrix - Development extension",
);

await expect(input).toBeEmpty();

await input.click();
await input.press(`${modifierKey}+m`);

await this.page.getByText("Keyboard ShortcutsPixieBrix").click();

await expect(input).toHaveValue(shortcut);
}
}
}
53 changes: 52 additions & 1 deletion end-to-end-tests/tests/extensionConsoleActivation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ import { test, expect } from "../fixtures/extensionBase";
import { ActivateModPage } from "../pageObjects/extensionConsole/modsPage";
// @ts-expect-error -- https://youtrack.jetbrains.com/issue/AQUA-711/Provide-a-run-configuration-for-Playwright-tests-in-specs-with-fixture-imports-only
import { type Page, test as base, type Frame } from "@playwright/test";
import { getSidebarPage, runModViaQuickBar } from "../utils";
import { getSidebarPage, openInNewPage, runModViaQuickBar } from "../utils";
import path from "node:path";
import { VALID_UUID_REGEX } from "@/types/stringTypes";
import { type Serializable } from "playwright-core/types/structs";
import { MV } from "../env";
import { ExtensionsShortcutsPage } from "end-to-end-tests/pageObjects/extensionsShortcutsPage";

test("can activate a mod with no config options", async ({
page,
Expand Down Expand Up @@ -164,3 +165,53 @@ test("can activate a mod with a database", async ({ page, extensionId }) => {

await expect(sideBarPage.getByTestId("card").getByText(note)).toBeHidden();
});

test("activating a mod when the quickbar shortcut is not configured", async ({
context,
page,
extensionId,
chromiumChannel,
}) => {
const modId = "@e2e-testing/show-alert";
grahamlangford marked this conversation as resolved.
Show resolved Hide resolved

const shortcutsPage = new ExtensionsShortcutsPage(page, chromiumChannel);

await shortcutsPage.goto();

await shortcutsPage.clearShortcut();

const newPage = await context.newPage();

const modActivationPage = new ActivateModPage(newPage, extensionId, modId);
await modActivationPage.goto();

await expect(
modActivationPage.keyboardShortcutDocumentationLink(),
).toBeVisible();
await modActivationPage.keyboardShortcutDocumentationLink().click();

await expect(
newPage.getByRole("heading", { name: "Changing the Quick Bar" }),
).toBeVisible();
await newPage.goBack();

await expect(modActivationPage.configureQuickbarShortcutLink()).toBeVisible();

const configureShortcutPage = await openInNewPage(
modActivationPage.configureQuickbarShortcutLink(),
context,
);

await expect(configureShortcutPage).toHaveURL(shortcutsPage.getPageUrl());
await configureShortcutPage.close();

await shortcutsPage.setShortcut();

await modActivationPage.clickActivateAndWaitForModsPageRedirect();

await page.bringToFront();
await page.goto("/");

await runModViaQuickBar(page, "Show Alert");
await expect(page.getByText("Quick Bar Action ran")).toBeVisible();
});
grahamlangford marked this conversation as resolved.
Show resolved Hide resolved
59 changes: 58 additions & 1 deletion end-to-end-tests/utils.ts
Copy link
Collaborator

@mnholtz mnholtz May 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opportunity to refactor runModViaQuickbar in this file, which currently works by trying both modifier keys

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@
*/

import type AxeBuilder from "@axe-core/playwright";
import { type Locator, expect, type Page, type Frame } from "@playwright/test";
import {
type Locator,
expect,
type Page,
type Frame,
type BrowserContext,
} from "@playwright/test";
import { MV } from "./env";

type AxeResults = Awaited<ReturnType<typeof AxeBuilder.prototype.analyze>>;
Expand Down Expand Up @@ -180,3 +186,54 @@ export async function conditionallyHoverOverMV2Sidebar(page: Page) {
await sidebarFrame.dispatchEvent("mouseenter");
}
}

/**
* Returns a reference to the new page that was opened.
* @param locator The anchor or button that opens the new page (must be clickable)
* @param context The browser context
*/
export async function openInNewPage(
grahamlangford marked this conversation as resolved.
Show resolved Hide resolved
locator: Locator,
context: BrowserContext,
): Promise<Page> {
const pagePromise = context.waitForEvent("page");

await locator.click();

return pagePromise;
}

// Temporary workaround for determining which modifiers to use for keyboard shortcuts
// A permanent fix has been merged but not released
// See: https://github.com/microsoft/playwright/pull/30572
export async function getBrowserOs(page: Page): Promise<string> {
let OSName: string;
const response = String(await page.evaluate(() => navigator.userAgent));
if (response.includes("Win")) {
OSName = "Windows";
}

if (response.includes("Mac")) {
OSName = "MacOS";
}

if (response.includes("X11")) {
OSName = "Unix";
}

if (response.includes("Linux")) {
OSName = "Linux";
}

return OSName;
}

export async function getModifierKey(page: Page): Promise<string> {
const OSName = await getBrowserOs(page);
return OSName === "MacOS" ? "Meta" : "Control";
}

export async function getModifierSymbol(page: Page): Promise<string> {
const OSName = await getBrowserOs(page);
return OSName === "MacOS" ? "⌘" : "⌃";
}
Loading