chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:25:07 +08:00
commit a26e856398
1681 changed files with 296950 additions and 0 deletions
+256
View File
@@ -0,0 +1,256 @@
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
// ┃ This file is part of the Perspective library, distributed under the terms ┃
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
import { defineConfig, devices } from "@playwright/experimental-ct-react";
import path from "path";
import * as dotenv from "dotenv";
import { createRequire } from "node:module";
import url from "node:url";
import { execSync } from "child_process";
// @ts-ignore -- sh_perspective.mjs is plain JS without type declarations
import { get_scope } from "../scripts/sh_perspective.mjs";
const __filename = url.fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
dotenv.config({ path: "./.perspectiverc", quiet: true });
Error.stackTraceLimit = Infinity;
// TODO Don't hardcode this. AFAICT this can only be accomplished by choosing
// the port before calling the playwright CLI, via env var.
const TEST_SERVER_PORT = 6598;
const RUN_JUPYTERLAB = !!process.env.PSP_JUPYTERLAB_TESTS;
// TODO use this from core
const package_venn = (get_scope() as string[]).reduce(
(acc: { include: string[]; exclude: string[] }, x: string) => {
if (x.startsWith("!")) {
acc.exclude.push(x);
} else {
acc.include.push(x);
}
return acc;
},
{ include: [] as string[], exclude: [] as string[] },
);
let PACKAGE: string[] = [];
if (package_venn.include.length === 0) {
PACKAGE = (
JSON.parse(execSync(`pnpm m ls --json --depth=-1`).toString()) as {
name?: string;
}[]
)
.filter((x): x is { name: string } => x.name !== undefined)
.map((x) => x.name.replace("@perspective-dev/", ""))
.filter((x: string) => package_venn.exclude.indexOf(`!${x}`) === -1);
} else {
PACKAGE = package_venn.include.filter(
(x: string) => package_venn.exclude.indexOf(`!${x}`) === -1,
);
}
const DEVICE_OPTIONS = {
"Desktop Chrome": {
// Lock DPR to 1 so WebGL viewport / canvas backing sizes are
// identical across host machines (matters for pixel snapshots).
// This also overrides the `devices["Desktop Chrome"]` default of 2.
deviceScaleFactor: 1,
launchOptions: {
args: [
// "--disable-accelerated-2d-canvas",
// "--disable-gpu",
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-dev-shm-usage",
"--font-render-hinting=none",
'--proxy-server="direct://"',
"--proxy-bypass-list=*",
"--js-flags=--expose-gc",
"--enable-precise-memory-info",
// Use the software WebGL backend so GPU/driver differences
// between machines don't leak into snapshot pixels. The
// 2× perf hit is under budget for the test suite.
"--use-gl=swiftshader",
"--use-angle=swiftshader",
"--force-color-profile=srgb",
"--disable-lcd-text",
],
},
},
};
const BROWSER_PACKAGES = [
{
packageName: "viewer",
testDir: "rust/perspective-viewer/test/js",
},
{
packageName: "react",
testDir: "packages/react/test/js",
},
{
packageName: "viewer-datagrid",
testDir: "packages/viewer-datagrid/test/js",
},
{
packageName: "viewer-charts",
testDir: "packages/viewer-charts/test/ts",
},
{
packageName: "jupyterlab",
testDir: "packages/jupyterlab/test/js",
},
{
packageName: "workspace",
testDir: "packages/workspace/test/js",
},
{
packageName: "docs",
testDir: "docs/test/js",
},
];
const NODE_PACKAGES = [
{
packageName: "client",
testDir: "rust/perspective-js/test/js",
},
];
const BROWSER_AND_PYTHON_PACKAGES = [
{
packageName: "python-perspective-jupyterlab",
testDir: "packages/jupyterlab/test/jupyter",
},
];
type ProjectConfig = NonNullable<
Parameters<typeof defineConfig>[0]["projects"]
>[number];
let PROJECTS = (() => {
const acc: ProjectConfig[] = [];
if (RUN_JUPYTERLAB) {
for (const pkg of BROWSER_AND_PYTHON_PACKAGES) {
for (const device of Object.keys(
DEVICE_OPTIONS,
) as (keyof typeof DEVICE_OPTIONS)[]) {
acc.push({
name: `${pkg.packageName}-${device
.toLowerCase()
.replace(" ", "-")}`,
testDir: path.join(__dirname, "../../", pkg.testDir),
use: {
...devices[device],
// baseURL: `http://localhost:${TEST_SERVER_PORT}`,
timezoneId: "UTC",
launchOptions: {
args: ["--js-flags=--expose-gc"],
},
},
});
}
}
} else {
for (const pkg of NODE_PACKAGES) {
if (PACKAGE == undefined || PACKAGE.includes(pkg.packageName)) {
acc.push({
name: `${pkg.packageName}-node`,
testDir: path.join(__dirname, "../../", pkg.testDir),
});
}
}
for (const pkg of BROWSER_PACKAGES) {
if (PACKAGE == undefined || PACKAGE.includes(pkg.packageName)) {
for (const device of Object.keys(
DEVICE_OPTIONS,
) as (keyof typeof DEVICE_OPTIONS)[]) {
acc.push({
name: `${pkg.packageName}-${device
.toLowerCase()
.replace(" ", "-")}`,
testDir: path.join(__dirname, "../../", pkg.testDir),
use: {
...devices[device],
...DEVICE_OPTIONS[device],
baseURL: `http://localhost:${TEST_SERVER_PORT}`,
timezoneId: "UTC",
},
});
}
}
}
}
return acc;
})();
const __require = createRequire(import.meta.url);
const GLOBAL_SETUP_PATH = __require.resolve(
"@perspective-dev/jupyterlab/test/config/jupyter/globalSetup.ts",
);
const GLOBAL_TEARDOWN_PATH = __require.resolve(
"@perspective-dev/jupyterlab/test/config/jupyter/globalTeardown.ts",
);
// See https://playwright.dev/docs/test-configuration.
export default defineConfig({
timeout: 30_000,
expect: {
timeout: 30_000,
},
repeatEach: process.env.PSP_SATURATE
? parseInt(process.env.PSP_SATURATE)
: 0,
forbidOnly: !!process.env.CI,
workers: process.env.PSP_DEBUG ? 1 : "50%",
retries: 0,
quiet: !process.env.PSP_DEBUG,
reporter: process.env.CI ? [["github"], ["html"]] : [["dot"]],
projects: PROJECTS,
outputDir: "dist/results",
use: {
launchOptions: {
slowMo: 500, // 500 milliseconds delay
},
headless: !process.env.PSP_HEADED,
ctPort: 3100,
viewport: { width: 1280, height: 720 },
actionTimeout: 0,
// trace: "retain-on-failure",
// screenshot: "only-on-failure",
// video: "retain-on-failure",
},
updateSnapshots: "none",
globalSetup: RUN_JUPYTERLAB
? GLOBAL_SETUP_PATH
: path.join(__dirname, "src/js/global_startup.ts"),
globalTeardown: RUN_JUPYTERLAB
? GLOBAL_TEARDOWN_PATH
: path.join(__dirname, "src/js/global_teardown.ts"),
snapshotPathTemplate:
"dist/snapshots/{projectName}/{testFilePath}/{arg}{ext}",
webServer: {
command: "tsx src/js/start_test_server.ts",
port: TEST_SERVER_PORT,
reuseExistingServer: true,
stdout: "pipe",
stderr: "pipe",
},
});