Skip to content

Commit

Permalink
fix some PR-related issues
Browse files Browse the repository at this point in the history
  • Loading branch information
grahamlangford committed Apr 25, 2024
2 parents b605288 + 1b2a1d9 commit f49232d
Show file tree
Hide file tree
Showing 43 changed files with 607 additions and 170 deletions.
13 changes: 11 additions & 2 deletions end-to-end-tests/tests/regressions/formFlicker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,21 @@ test.describe("forms flickering due to components unexpectedly unmounting/remoun

const sideBarPage = await getSidebarPage(page, extensionId);

await expect(sideBarPage.getByTestId("container").nth(1)).toContainText(
"Welcome to the Snippet Manager!",
);

const input = sideBarPage.getByPlaceholder("Search snippets");
await input.click();
// Add delay to give time for the the input to lose focus
await input.pressSequentially("abc", { delay: 100 });
await input.pressSequentially("lor", { delay: 100 });

// Validate that the input value was set correctly
await expect(input).toHaveValue("abc");
await expect(input).toHaveValue("lor");

// Verify that the input value filtered the list
await expect(sideBarPage.getByTestId("container").nth(1)).toContainText(
"Lorem ipsum dolor sit amet, ",
);
});
});
78 changes: 78 additions & 0 deletions end-to-end-tests/tests/runtime/sidebarController.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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 { 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 } from "@playwright/test";
import { getSidebarPage, isSidebarOpen } from "../../utils";
import { MV } from "../../env";

test.describe("sidebar controller", () => {
test("can open sidebar immediately from iframe without focus dialog", async ({
page,
extensionId,
}) => {
const modId = "@pixies/test/frame-sidebar-actions";

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

await page.goto("/frames-builder.html");

const frame = page.frameLocator("iframe");
await frame.getByRole("link", { name: "Show Sidebar Immediately" }).click();

// Don't use getSidebarPage because it automatically clicks the MV3 focus dialog.
await expect(() => {
expect(isSidebarOpen(page, extensionId)).toBe(false);
}).toPass({ timeout: 5000 });
});

test("shows focus dialog in top-level frame", async ({
page,
extensionId,
}) => {
test.skip(MV === "2", "This test is only relevant for MV3");

const modId = "@pixies/test/frame-sidebar-actions";

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

await page.goto("/frames-builder.html");

const frame = page.frameLocator("iframe");

// Mod waits 7.5 seconds before running Show Sidebar brick to ensure the user gesture dialog is shown
await frame.getByRole("link", { name: "Show Sidebar after Wait" }).click();
// eslint-disable-next-line playwright/no-wait-for-timeout -- match wait in the mod
await page.waitForTimeout(8000);

// Focus dialog should be visible in the top-level frame
await expect(page.getByRole("button", { name: "OK" })).toBeVisible();

// The focus dialog should not be shown in the iframe. Check after checking the top-level frame
// because it's a positive check for the dialog being shown.
await expect(frame.getByRole("button", { name: "OK" })).not.toBeVisible();

// Will error if page/frame not available
await getSidebarPage(page, extensionId);
});
});
12 changes: 9 additions & 3 deletions scripts/__snapshots__/manifest.test.js.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 11 additions & 13 deletions scripts/manifest.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ import Policy from "csp-parse";
import { normalizeManifestPermissions } from "webext-permissions";
import { excludeDuplicatePatterns } from "webext-patterns";

function getVersion(env, isBetaListing) {
function getVersion(env) {
const stageMap = {
alpha: 1000,
beta: 2000,
release: 3000,
};

// `manifest.json` only supports numbers in the version, so use the semver
Expand All @@ -32,19 +33,16 @@ function getVersion(env, isBetaListing) {
);
const { version, stage, stageNumber } = match.groups;

// Add 4th digit for alpha/beta release builds. Used to update the extension BETA listing in the Chrome Web Store.
if (isBetaListing) {
if (stage && stageNumber) {
// Ex: 1.8.13-alpha.1 -> 1.8.13.1001
// Ex: 1.8.13-beta.55 -> 1.8.13.2055
return `${version}.${stageMap[stage] + Number(stageNumber)}`;
}

// Ex: 1.8.13.3000 -- Ensures that the release build version number is greater than the alpha/beta build version numbers
return `${version}.3000`;
// Add 4th digit for differentiating alpha/beta/stable release builds.
// Used primarily to update the extension BETA listing in the Chrome Web Store.
if (stage && stageNumber) {
// Ex: 1.8.13-alpha.1 -> 1.8.13.1001
// Ex: 1.8.13-beta.55 -> 1.8.13.2055
return `${version}.${stageMap[stage] + Number(stageNumber)}`;
}

return version;
// Ex: 1.8.13.3000 -- Ensures that the release build version number is greater than the alpha/beta build version numbers
return `${version}.${stageMap.release}`;
}

function getVersionName(env, isProduction) {
Expand Down Expand Up @@ -146,7 +144,7 @@ function addInternalUrlsToContentScripts(manifest, internal) {
function customizeManifest(manifestV2, options = {}) {
const { isProduction, manifestVersion, env = {}, isBeta } = options;
const manifest = structuredClone(manifestV2);
manifest.version = getVersion(env, isBeta);
manifest.version = getVersion(env);
manifest.version_name = getVersionName(env, isProduction);

if (!isProduction) {
Expand Down
98 changes: 68 additions & 30 deletions scripts/manifest.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,83 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/* eslint-disable @shopify/jest/no-snapshots -- We want to specifically commit the entire customized manifest as a snapshot */
/* eslint-disable no-restricted-imports -- Aliases don't work outside built files */

import { omit } from "lodash";
import manifest from "../src/manifest.json";
import { loadEnv } from "./env.mjs";
import customizeManifest from "./manifest.mjs";

loadEnv();

const cleanCustomize = (...args) =>
omit(customizeManifest(...args), ["version", "version_name", "key"]);
const cleanCustomize = (...args) => omit(customizeManifest(...args), ["key"]);

describe("customizeManifest", () => {
test("mv2", () => {
expect(
cleanCustomize(manifest, {
env: process.env,
isProduction: true,
}),
).toMatchSnapshot();
});
test("mv3", () => {
expect(
cleanCustomize(manifest, {
env: process.env,
isProduction: true,
manifestVersion: 3,
}),
).toMatchSnapshot();
describe("release builds", () => {
test("mv2", () => {
expect(
cleanCustomize(manifest, {
// eslint-disable-next-line camelcase -- auto-inserted
env: { ...process.env, npm_package_version: "1.8.13" },
isProduction: true,
}),
).toMatchSnapshot();
});

test("mv3", () => {
expect(
cleanCustomize(manifest, {
// eslint-disable-next-line camelcase -- auto-inserted
env: { ...process.env, npm_package_version: "1.8.13" },
isProduction: true,
manifestVersion: 3,
}),
).toMatchSnapshot();
});

test("beta", () => {
expect(
cleanCustomize(manifest, {
// eslint-disable-next-line camelcase -- auto-inserted
env: { ...process.env, npm_package_version: "1.8.13" },
isProduction: true,
manifestVersion: 3,
isBeta: true,
}),
).toMatchSnapshot();
});
});
test("beta", () => {
expect(
cleanCustomize(manifest, {
env: process.env,
isProduction: true,
manifestVersion: 3,
isBeta: true,
}),
).toMatchSnapshot();

describe("four digit versioning", () => {
test("alpha version", () => {
expect(
cleanCustomize(manifest, {
// eslint-disable-next-line camelcase -- auto-inserted
env: { ...process.env, npm_package_version: "1.8.13-alpha.123" },
isProduction: true,
manifestVersion: 3,
}),
).toContainEntry(["version", "1.8.13.1123"]);
});

test("beta version", () => {
expect(
cleanCustomize(manifest, {
// eslint-disable-next-line camelcase -- auto-inserted
env: { ...process.env, npm_package_version: "1.8.13-beta.123" },
isProduction: true,
manifestVersion: 3,
}),
).toContainEntry(["version", "1.8.13.2123"]);
});

test("release version", () => {
expect(
cleanCustomize(manifest, {
// eslint-disable-next-line camelcase -- auto-inserted
env: { ...process.env, npm_package_version: "1.8.13" },
isProduction: true,
manifestVersion: 3,
}),
).toContainEntry(["version", "1.8.13.3000"]);
});
});
});
11 changes: 9 additions & 2 deletions src/analysis/analysisVisitors/varAnalysis/varAnalysis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { CustomFormRenderer } from "@/bricks/renderers/customForm";
import { toExpression } from "@/utils/expressionUtils";
import IdentityTransformer from "@/bricks/transformers/IdentityTransformer";
import { createNewConfiguredBrick } from "@/pageEditor/exampleBrickConfigs";
import pixiebrixIntegrationDependencyFactory from "@/integrations/util/pixiebrixIntegrationDependencyFactory";

jest.mocked(services.locate).mockResolvedValue(
sanitizedIntegrationConfigFactory({
Expand Down Expand Up @@ -134,13 +135,14 @@ describe("Collecting available vars", () => {

const extension = formStateFactory(
{
// Let this extension have an integration dependency
// Test both the PixieBrix api integration and a sample third-party service
integrationDependencies: [
integrationDependencyFactory({
integrationId: validateRegistryId("@test/service"),
outputKey: validateOutputKey("pixiebrix"),
outputKey: validateOutputKey("testService"),
configId: uuidSequence,
}),
pixiebrixIntegrationDependencyFactory(),
],
optionsArgs: {
foo: "bar",
Expand All @@ -164,6 +166,11 @@ describe("Collecting available vars", () => {

expect(foundationKnownVars.isVariableDefined("@options.foo")).toBeTrue();

expect(
foundationKnownVars.isVariableDefined(
"@testService.__service.serviceId",
),
).toBeTrue();
expect(
foundationKnownVars.isVariableDefined("@pixiebrix.__service.serviceId"),
).toBeTrue();
Expand Down
7 changes: 1 addition & 6 deletions src/analysis/analysisVisitors/varAnalysis/varAnalysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import { MOD_VARIABLE_REFERENCE } from "@/runtime/extendModVariableContext";
import { joinPathParts } from "@/utils/formUtils";
import makeIntegrationsContextFromDependencies from "@/integrations/util/makeIntegrationsContextFromDependencies";
import { getOutputReference, isOutputKey } from "@/runtime/runtimeTypes";
import { PIXIEBRIX_INTEGRATION_ID } from "@/integrations/constants";

export const INVALID_VARIABLE_GENERIC_MESSAGE = "Invalid variable name";

Expand Down Expand Up @@ -114,13 +113,9 @@ async function setIntegrationDependencyVars(
{ integrationDependencies = [] }: ModComponentFormState,
contextVars: VarMap,
): Promise<void> {
// We don't want to make the pixiebrix api integration available as a variable
const nonPbDependencies = integrationDependencies.filter(
(dependency) => dependency.integrationId !== PIXIEBRIX_INTEGRATION_ID,
);
// Loop through all the dependencies, so we can set the source for each dependency variable properly
await Promise.all(
nonPbDependencies.map(async (integrationDependency) => {
integrationDependencies.map(async (integrationDependency) => {
const serviceContext = await makeIntegrationsContextFromDependencies([
integrationDependency,
]);
Expand Down
Loading

0 comments on commit f49232d

Please sign in to comment.