mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-08-22 01:37:04 +02:00
Compare commits
3 Commits
feat/e2e-t
...
release
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f29e9df72d | ||
![]() |
b5ad7ae4e3 | ||
![]() |
c78e4aab7f |
27
.github/workflows/playwright.yml
vendored
27
.github/workflows/playwright.yml
vendored
@@ -1,27 +0,0 @@
|
||||
name: Playwright Tests
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master ]
|
||||
pull_request:
|
||||
branches: [ main, master ]
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
- name: Install dependencies
|
||||
run: npm install -g yarn && yarn
|
||||
- name: Install Playwright Browsers
|
||||
run: yarn playwright install --with-deps
|
||||
- name: Run Playwright tests
|
||||
run: yarn playwright test
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 30
|
6
.gitignore
vendored
6
.gitignore
vendored
@@ -27,9 +27,3 @@ dev-dist
|
||||
html
|
||||
meta*.json
|
||||
.claude
|
||||
|
||||
# Playwright
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
|
@@ -20,7 +20,6 @@ import {
|
||||
APP_NAME,
|
||||
EVENT,
|
||||
THEME,
|
||||
TITLE_TIMEOUT,
|
||||
VERSION_TIMEOUT,
|
||||
debounce,
|
||||
getVersion,
|
||||
@@ -74,7 +73,6 @@ import type {
|
||||
import type { ResolutionType } from "@excalidraw/common/utility-types";
|
||||
import type { ResolvablePromise } from "@excalidraw/common/utils";
|
||||
|
||||
import "./record";
|
||||
import CustomStats from "./CustomStats";
|
||||
import {
|
||||
Provider,
|
||||
@@ -500,11 +498,6 @@ const ExcalidrawWrapper = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const titleTimeout = setTimeout(
|
||||
() => (document.title = APP_NAME),
|
||||
TITLE_TIMEOUT,
|
||||
);
|
||||
|
||||
const syncData = debounce(() => {
|
||||
if (isTestEnv()) {
|
||||
return;
|
||||
@@ -595,7 +588,6 @@ const ExcalidrawWrapper = () => {
|
||||
visibilityChange,
|
||||
false,
|
||||
);
|
||||
clearTimeout(titleTimeout);
|
||||
};
|
||||
}, [isCollabDisabled, collabAPI, excalidrawAPI, setLangCode]);
|
||||
|
||||
|
@@ -2,9 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>
|
||||
Free, collaborative whiteboard • Hand-drawn look & feel | Excalidraw
|
||||
</title>
|
||||
<title>Excalidraw Whiteboard</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover, shrink-to-fit=no"
|
||||
|
@@ -1,245 +0,0 @@
|
||||
declare global {
|
||||
interface Window {
|
||||
record: typeof Record;
|
||||
}
|
||||
}
|
||||
|
||||
export type PlaybackEvent = (
|
||||
| {
|
||||
type: "mouse.move";
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
| {
|
||||
type: "mouse.down" | "mouse.up";
|
||||
button: "left" | "right" | "middle";
|
||||
}
|
||||
| {
|
||||
type: "keyboard.down" | "keyboard.up";
|
||||
key: string;
|
||||
}
|
||||
| {
|
||||
type: "header";
|
||||
width: number;
|
||||
height: number;
|
||||
localStorage: { [key: string]: string };
|
||||
}
|
||||
) & {
|
||||
delay: number;
|
||||
};
|
||||
|
||||
export class Record {
|
||||
private static events: PlaybackEvent[] = [];
|
||||
private static timestamp: number = 0;
|
||||
|
||||
public static start() {
|
||||
// capture a snapshot of localStorage (if available) to include in the header
|
||||
const lsSnapshot: { [key: string]: string } = {};
|
||||
try {
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
if (key != null) {
|
||||
lsSnapshot[key] = localStorage.getItem(key) ?? "";
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
Record.events = [
|
||||
{
|
||||
type: "header",
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
localStorage: lsSnapshot,
|
||||
delay: 0,
|
||||
},
|
||||
];
|
||||
Record.timestamp = performance.now();
|
||||
|
||||
window.addEventListener("mousemove", this.onMouseMove);
|
||||
window.addEventListener("mousedown", this.onMouseDown);
|
||||
window.addEventListener("mouseup", this.onMouseUp);
|
||||
window.addEventListener("keydown", this.onKeyDown);
|
||||
window.addEventListener("keyup", this.onKeyUp);
|
||||
|
||||
try {
|
||||
const canvases = Array.from(
|
||||
document.querySelectorAll("canvas"),
|
||||
) as HTMLCanvasElement[];
|
||||
for (const c of canvases) {
|
||||
c.addEventListener("mousemove", this.onMouseMove);
|
||||
c.addEventListener("mousedown", this.onMouseDown);
|
||||
c.addEventListener("mouseup", this.onMouseUp);
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
public static stop() {
|
||||
window.removeEventListener("mousemove", this.onMouseMove);
|
||||
window.removeEventListener("mousedown", this.onMouseDown);
|
||||
window.removeEventListener("mouseup", this.onMouseUp);
|
||||
window.removeEventListener("keydown", this.onKeyDown);
|
||||
window.removeEventListener("keyup", this.onKeyUp);
|
||||
|
||||
// Remove listeners from any canvases we attached to
|
||||
try {
|
||||
const canvases = Array.from(
|
||||
document.querySelectorAll("canvas"),
|
||||
) as HTMLCanvasElement[];
|
||||
for (const c of canvases) {
|
||||
c.removeEventListener("mousemove", this.onMouseMove);
|
||||
c.removeEventListener("mousedown", this.onMouseDown);
|
||||
c.removeEventListener("mouseup", this.onMouseUp);
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/// Displays a window as an absolutely positioned DIV with the generated
|
||||
/// events within <pre> tags as formatted JSON, so it can be copied easily.
|
||||
public static showGeneratedEvents() {
|
||||
const div = document.createElement("div");
|
||||
div.style.position = "absolute";
|
||||
div.style.top = "10px";
|
||||
div.style.right = "10px";
|
||||
div.style.left = "10px";
|
||||
div.style.height = "60vh";
|
||||
div.style.backgroundColor = "gray";
|
||||
div.style.padding = "10px";
|
||||
div.style.zIndex = "10000";
|
||||
|
||||
const pre = document.createElement("pre");
|
||||
pre.textContent = JSON.stringify(this.events, null, 2);
|
||||
// avoid overlap with the close button and limit height for large event dumps
|
||||
pre.style.marginTop = "18px";
|
||||
pre.style.maxHeight = "60vh";
|
||||
pre.style.overflow = "auto";
|
||||
div.appendChild(pre);
|
||||
|
||||
const copyBtn = document.createElement("button");
|
||||
copyBtn.textContent = "Copy";
|
||||
copyBtn.title = "Copy generated events to clipboard";
|
||||
copyBtn.setAttribute("aria-label", "Copy generated events to clipboard");
|
||||
copyBtn.style.position = "absolute";
|
||||
copyBtn.style.top = "4px";
|
||||
copyBtn.style.left = "4px";
|
||||
copyBtn.style.border = "none";
|
||||
copyBtn.style.background = "transparent";
|
||||
copyBtn.style.fontSize = "12px";
|
||||
copyBtn.style.lineHeight = "1";
|
||||
copyBtn.style.cursor = "pointer";
|
||||
copyBtn.style.padding = "4px 8px";
|
||||
copyBtn.addEventListener("click", async () => {
|
||||
const text = pre.textContent ?? "";
|
||||
try {
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
await navigator.clipboard.writeText(text);
|
||||
} else {
|
||||
const ta = document.createElement("textarea");
|
||||
ta.value = text;
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(ta);
|
||||
}
|
||||
const orig = copyBtn.textContent;
|
||||
copyBtn.textContent = "Copied";
|
||||
setTimeout(() => (copyBtn.textContent = orig), 1000);
|
||||
} catch {}
|
||||
});
|
||||
div.appendChild(copyBtn);
|
||||
|
||||
const closeBtn = document.createElement("button");
|
||||
closeBtn.textContent = "×";
|
||||
closeBtn.title = "Close";
|
||||
closeBtn.style.position = "absolute";
|
||||
closeBtn.style.top = "4px";
|
||||
closeBtn.style.right = "4px";
|
||||
closeBtn.style.border = "none";
|
||||
closeBtn.style.background = "transparent";
|
||||
closeBtn.style.fontSize = "18px";
|
||||
closeBtn.style.lineHeight = "1";
|
||||
closeBtn.style.cursor = "pointer";
|
||||
closeBtn.addEventListener("click", () => {
|
||||
// remove the dialog from DOM
|
||||
if (div.parentNode) {
|
||||
div.parentNode.removeChild(div);
|
||||
}
|
||||
});
|
||||
div.appendChild(closeBtn);
|
||||
|
||||
document.body.appendChild(div);
|
||||
}
|
||||
|
||||
private static onMouseMove(event: MouseEvent) {
|
||||
if (
|
||||
event.clientX < 0 ||
|
||||
event.clientX > window.innerWidth ||
|
||||
event.clientY < 0 ||
|
||||
event.clientY > window.innerHeight
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const now = event.timeStamp || performance.now();
|
||||
const delay = now - Record.timestamp;
|
||||
Record.timestamp = now;
|
||||
|
||||
Record.events.push({
|
||||
type: "mouse.move",
|
||||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
delay,
|
||||
});
|
||||
}
|
||||
|
||||
private static onMouseDown(event: MouseEvent) {
|
||||
const now = event.timeStamp || performance.now();
|
||||
const delay = now - Record.timestamp;
|
||||
Record.timestamp = now;
|
||||
|
||||
Record.events.push({
|
||||
type: "mouse.down",
|
||||
button:
|
||||
event.button === 0 ? "left" : event.button === 1 ? "middle" : "right",
|
||||
delay,
|
||||
});
|
||||
}
|
||||
|
||||
private static onMouseUp(event: MouseEvent) {
|
||||
const now = event.timeStamp || performance.now();
|
||||
const delay = now - Record.timestamp;
|
||||
Record.timestamp = now;
|
||||
|
||||
Record.events.push({
|
||||
type: "mouse.up",
|
||||
button:
|
||||
event.button === 0 ? "left" : event.button === 1 ? "middle" : "right",
|
||||
delay,
|
||||
});
|
||||
}
|
||||
|
||||
private static onKeyDown(event: KeyboardEvent) {
|
||||
const now = event.timeStamp || performance.now();
|
||||
const delay = now - Record.timestamp;
|
||||
Record.timestamp = now;
|
||||
|
||||
Record.events.push({
|
||||
type: "keyboard.down",
|
||||
key: event.key,
|
||||
delay,
|
||||
});
|
||||
}
|
||||
|
||||
private static onKeyUp(event: KeyboardEvent) {
|
||||
const now = event.timeStamp || performance.now();
|
||||
const delay = now - Record.timestamp;
|
||||
Record.timestamp = now;
|
||||
|
||||
Record.events.push({
|
||||
type: "keyboard.up",
|
||||
key: event.key,
|
||||
delay,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
window.record = Record;
|
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
||||
import { expect, type Page } from "@playwright/test";
|
||||
|
||||
import type { PlaybackEvent } from "../../record";
|
||||
|
||||
export async function playbackEvents(page: Page, events: PlaybackEvent[]) {
|
||||
const mask = [
|
||||
page.getByRole("button", { name: "Share" }),
|
||||
page.getByTitle("Library").locator("div"),
|
||||
];
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
page.setDefaultTimeout(100000);
|
||||
for (const event of events) {
|
||||
// Handle header event specially: set viewport and localStorage before playback
|
||||
if (event.type === "header") {
|
||||
// set viewport to recorded size
|
||||
await page.setViewportSize({ width: event.width, height: event.height });
|
||||
width = event.width;
|
||||
height = event.height;
|
||||
|
||||
// apply localStorage snapshot in page context
|
||||
if (event.localStorage) {
|
||||
await page.evaluate((ls: Record<string, string>) => {
|
||||
try {
|
||||
for (const k in ls) {
|
||||
if (Object.prototype.hasOwnProperty.call(ls, k)) {
|
||||
localStorage.setItem(k, ls[k]);
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
}, event.localStorage as Record<string, string>);
|
||||
}
|
||||
|
||||
await page.reload();
|
||||
|
||||
await page.waitForLoadState("load");
|
||||
|
||||
// header has no further action
|
||||
continue;
|
||||
}
|
||||
// wait the recorded delay before dispatching the event
|
||||
const ms = Math.max(0, Math.round((event as any).delay ?? 0));
|
||||
if (ms > 0) {
|
||||
await page.waitForTimeout(ms);
|
||||
}
|
||||
switch (event.type) {
|
||||
case "mouse.move":
|
||||
// Simulate mouse movement
|
||||
if (event.x < 0 || event.x > width || event.y < 0 || event.y > height) {
|
||||
break;
|
||||
}
|
||||
await page.mouse.move(event.x, event.y);
|
||||
break;
|
||||
case "mouse.down":
|
||||
// Simulate mouse button down
|
||||
await page.mouse.down({ button: event.button });
|
||||
break;
|
||||
case "mouse.up":
|
||||
// Simulate mouse button up
|
||||
await page.mouse.up({ button: event.button });
|
||||
await expect(page).toHaveScreenshot({ maxDiffPixels: 100, mask });
|
||||
break;
|
||||
case "keyboard.down":
|
||||
// Simulate key down
|
||||
await page.keyboard.down(event.key);
|
||||
break;
|
||||
case "keyboard.up":
|
||||
// Simulate key up
|
||||
await page.keyboard.up(event.key);
|
||||
await expect(page).toHaveScreenshot({
|
||||
maxDiffPixels: 100,
|
||||
mask,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@@ -11,11 +11,9 @@
|
||||
"@babel/preset-env": "7.26.9",
|
||||
"@excalidraw/eslint-config": "1.0.3",
|
||||
"@excalidraw/prettier-config": "1.0.2",
|
||||
"@playwright/test": "1.55.0",
|
||||
"@types/chai": "4.3.0",
|
||||
"@types/jest": "27.4.0",
|
||||
"@types/lodash.throttle": "4.1.7",
|
||||
"@types/node": "24.3.0",
|
||||
"@types/react": "19.0.10",
|
||||
"@types/react-dom": "19.0.4",
|
||||
"@types/socket.io-client": "3.0.0",
|
||||
|
@@ -1111,16 +1111,16 @@ export class ElementsDelta implements DeltaContainer<SceneElementsMap> {
|
||||
inserted,
|
||||
}: Delta<ElementPartial>) =>
|
||||
!!(
|
||||
deleted.version &&
|
||||
inserted.version &&
|
||||
// versions are required integers
|
||||
Number.isInteger(deleted.version) &&
|
||||
Number.isInteger(inserted.version) &&
|
||||
// versions should be positive, zero included
|
||||
deleted.version >= 0 &&
|
||||
inserted.version >= 0 &&
|
||||
// versions should never be the same
|
||||
deleted.version !== inserted.version
|
||||
(
|
||||
Number.isInteger(deleted.version) &&
|
||||
Number.isInteger(inserted.version) &&
|
||||
// versions should be positive, zero included
|
||||
deleted.version! >= 0 &&
|
||||
inserted.version! >= 0 &&
|
||||
// versions should never be the same
|
||||
deleted.version !== inserted.version
|
||||
)
|
||||
);
|
||||
|
||||
private static satisfiesUniqueInvariants = (
|
||||
@@ -1191,9 +1191,10 @@ export class ElementsDelta implements DeltaContainer<SceneElementsMap> {
|
||||
ElementsDelta.stripIrrelevantProps,
|
||||
);
|
||||
|
||||
// ignore updates which would "delete" already deleted element
|
||||
if (!prevElement.isDeleted) {
|
||||
removed[prevElement.id] = delta;
|
||||
} else {
|
||||
updated[prevElement.id] = delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1221,6 +1222,8 @@ export class ElementsDelta implements DeltaContainer<SceneElementsMap> {
|
||||
// ignore updates which would "delete" already deleted element
|
||||
if (!nextElement.isDeleted) {
|
||||
added[nextElement.id] = delta;
|
||||
} else {
|
||||
updated[nextElement.id] = delta;
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -1250,15 +1253,7 @@ export class ElementsDelta implements DeltaContainer<SceneElementsMap> {
|
||||
continue;
|
||||
}
|
||||
|
||||
const strippedDeleted = ElementsDelta.stripVersionProps(delta.deleted);
|
||||
const strippedInserted = ElementsDelta.stripVersionProps(
|
||||
delta.inserted,
|
||||
);
|
||||
|
||||
// making sure there are at least some changes and only changed version & versionNonce does not count!
|
||||
if (Delta.isInnerDifferent(strippedDeleted, strippedInserted, true)) {
|
||||
updated[nextElement.id] = delta;
|
||||
}
|
||||
updated[nextElement.id] = delta;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1372,15 +1367,8 @@ export class ElementsDelta implements DeltaContainer<SceneElementsMap> {
|
||||
latestDelta = delta;
|
||||
}
|
||||
|
||||
const strippedDeleted = ElementsDelta.stripVersionProps(
|
||||
latestDelta.deleted,
|
||||
);
|
||||
const strippedInserted = ElementsDelta.stripVersionProps(
|
||||
latestDelta.inserted,
|
||||
);
|
||||
|
||||
// it might happen that after applying latest changes the delta itself does not contain any changes
|
||||
if (Delta.isInnerDifferent(strippedDeleted, strippedInserted)) {
|
||||
if (Delta.isInnerDifferent(latestDelta.deleted, latestDelta.inserted)) {
|
||||
modifiedDeltas[id] = latestDelta;
|
||||
}
|
||||
}
|
||||
@@ -2075,12 +2063,4 @@ export class ElementsDelta implements DeltaContainer<SceneElementsMap> {
|
||||
|
||||
return strippedPartial;
|
||||
}
|
||||
|
||||
private static stripVersionProps(
|
||||
partial: Partial<OrderedExcalidrawElement>,
|
||||
): ElementPartial {
|
||||
const { version, versionNonce, ...strippedPartial } = partial;
|
||||
|
||||
return strippedPartial;
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ import { AppStateDelta, Delta, ElementsDelta } from "../src/delta";
|
||||
|
||||
describe("ElementsDelta", () => {
|
||||
describe("elements delta calculation", () => {
|
||||
it("should not create removed delta when element gets removed but was already deleted", () => {
|
||||
it("should not throw when element gets removed but was already deleted", () => {
|
||||
const element = API.createElement({
|
||||
type: "rectangle",
|
||||
x: 100,
|
||||
@@ -19,12 +19,12 @@ describe("ElementsDelta", () => {
|
||||
const prevElements = new Map([[element.id, element]]);
|
||||
const nextElements = new Map();
|
||||
|
||||
const delta = ElementsDelta.calculate(prevElements, nextElements);
|
||||
|
||||
expect(delta.isEmpty()).toBeTruthy();
|
||||
expect(() =>
|
||||
ElementsDelta.calculate(prevElements, nextElements),
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it("should not create added delta when adding element as already deleted", () => {
|
||||
it("should not throw when adding element as already deleted", () => {
|
||||
const element = API.createElement({
|
||||
type: "rectangle",
|
||||
x: 100,
|
||||
@@ -35,12 +35,12 @@ describe("ElementsDelta", () => {
|
||||
const prevElements = new Map();
|
||||
const nextElements = new Map([[element.id, element]]);
|
||||
|
||||
const delta = ElementsDelta.calculate(prevElements, nextElements);
|
||||
|
||||
expect(delta.isEmpty()).toBeTruthy();
|
||||
expect(() =>
|
||||
ElementsDelta.calculate(prevElements, nextElements),
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it("should not create updated delta when there is only version and versionNonce change", () => {
|
||||
it("should create updated delta even when there is only version and versionNonce change", () => {
|
||||
const baseElement = API.createElement({
|
||||
type: "rectangle",
|
||||
x: 100,
|
||||
@@ -65,7 +65,24 @@ describe("ElementsDelta", () => {
|
||||
nextElements as SceneElementsMap,
|
||||
);
|
||||
|
||||
expect(delta.isEmpty()).toBeTruthy();
|
||||
expect(delta).toEqual(
|
||||
ElementsDelta.create(
|
||||
{},
|
||||
{},
|
||||
{
|
||||
[baseElement.id]: Delta.create(
|
||||
{
|
||||
version: baseElement.version,
|
||||
versionNonce: baseElement.versionNonce,
|
||||
},
|
||||
{
|
||||
version: baseElement.version + 1,
|
||||
versionNonce: baseElement.versionNonce + 1,
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -83,7 +83,7 @@
|
||||
"@excalidraw/element": "0.18.0",
|
||||
"@excalidraw/math": "0.18.0",
|
||||
"@excalidraw/laser-pointer": "1.3.1",
|
||||
"@excalidraw/mermaid-to-excalidraw": "1.1.2",
|
||||
"@excalidraw/mermaid-to-excalidraw": "1.1.3",
|
||||
"@excalidraw/random-username": "1.1.0",
|
||||
"@radix-ui/react-popover": "1.1.6",
|
||||
"@radix-ui/react-tabs": "1.1.3",
|
||||
|
@@ -282,6 +282,14 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
"added": {},
|
||||
"removed": {},
|
||||
"updated": {
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"version": 12,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 11,
|
||||
},
|
||||
},
|
||||
"id1": {
|
||||
"deleted": {
|
||||
"boundElements": [],
|
||||
@@ -396,6 +404,14 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
"version": 12,
|
||||
},
|
||||
},
|
||||
"id15": {
|
||||
"deleted": {
|
||||
"version": 10,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 9,
|
||||
},
|
||||
},
|
||||
"id4": {
|
||||
"deleted": {
|
||||
"height": "99.19972",
|
||||
@@ -837,6 +853,14 @@ exports[`history > multiplayer undo/redo > conflicts in arrows and their bindabl
|
||||
"added": {},
|
||||
"removed": {},
|
||||
"updated": {
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"version": 13,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 12,
|
||||
},
|
||||
},
|
||||
"id1": {
|
||||
"deleted": {
|
||||
"boundElements": [],
|
||||
@@ -2632,7 +2656,7 @@ exports[`history > multiplayer undo/redo > conflicts in bound text elements and
|
||||
"height": 100,
|
||||
"id": "id0",
|
||||
"index": "a0",
|
||||
"isDeleted": true,
|
||||
"isDeleted": false,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"opacity": 100,
|
||||
@@ -2681,7 +2705,7 @@ exports[`history > multiplayer undo/redo > conflicts in bound text elements and
|
||||
"textAlign": "left",
|
||||
"type": "text",
|
||||
"updated": 1,
|
||||
"version": 6,
|
||||
"version": 8,
|
||||
"verticalAlign": "top",
|
||||
"width": 100,
|
||||
"x": 15,
|
||||
@@ -2695,7 +2719,7 @@ exports[`history > multiplayer undo/redo > conflicts in bound text elements and
|
||||
"autoResize": true,
|
||||
"backgroundColor": "transparent",
|
||||
"boundElements": null,
|
||||
"containerId": null,
|
||||
"containerId": "id0",
|
||||
"customData": undefined,
|
||||
"fillStyle": "solid",
|
||||
"fontFamily": 5,
|
||||
@@ -2742,10 +2766,12 @@ exports[`history > multiplayer undo/redo > conflicts in bound text elements and
|
||||
},
|
||||
},
|
||||
"elements": {
|
||||
"added": {
|
||||
"added": {},
|
||||
"removed": {},
|
||||
"updated": {
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"isDeleted": true,
|
||||
"isDeleted": false,
|
||||
"version": 9,
|
||||
},
|
||||
"inserted": {
|
||||
@@ -2774,16 +2800,21 @@ exports[`history > multiplayer undo/redo > conflicts in bound text elements and
|
||||
"y": 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
"removed": {},
|
||||
"updated": {
|
||||
"id5": {
|
||||
"id1": {
|
||||
"deleted": {
|
||||
"containerId": null,
|
||||
"version": 8,
|
||||
},
|
||||
"inserted": {
|
||||
"containerId": null,
|
||||
"version": 7,
|
||||
},
|
||||
},
|
||||
"id5": {
|
||||
"deleted": {
|
||||
"version": 7,
|
||||
},
|
||||
"inserted": {
|
||||
"containerId": "id0",
|
||||
"version": 6,
|
||||
},
|
||||
},
|
||||
@@ -3096,6 +3127,14 @@ exports[`history > multiplayer undo/redo > conflicts in bound text elements and
|
||||
"version": 8,
|
||||
},
|
||||
},
|
||||
"id5": {
|
||||
"deleted": {
|
||||
"version": 7,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": "id9",
|
||||
@@ -4645,15 +4684,15 @@ exports[`history > multiplayer undo/redo > conflicts in bound text elements and
|
||||
"id1": {
|
||||
"deleted": {
|
||||
"angle": 0,
|
||||
"version": 4,
|
||||
"version": 8,
|
||||
"x": 15,
|
||||
"y": 15,
|
||||
},
|
||||
"inserted": {
|
||||
"angle": 90,
|
||||
"version": 3,
|
||||
"x": 205,
|
||||
"y": 205,
|
||||
"angle": 0,
|
||||
"version": 7,
|
||||
"x": 15,
|
||||
"y": 15,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -5632,12 +5671,12 @@ exports[`history > multiplayer undo/redo > conflicts in frames and their childre
|
||||
"updated": {
|
||||
"id1": {
|
||||
"deleted": {
|
||||
"frameId": "id0",
|
||||
"version": 5,
|
||||
"frameId": null,
|
||||
"version": 9,
|
||||
},
|
||||
"inserted": {
|
||||
"frameId": null,
|
||||
"version": 6,
|
||||
"version": 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -5784,7 +5823,7 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 5,
|
||||
"version": 6,
|
||||
"width": 100,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
@@ -5816,7 +5855,7 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"version": 5,
|
||||
"width": 100,
|
||||
"x": 100,
|
||||
"y": 100,
|
||||
@@ -5852,7 +5891,74 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"elements": {
|
||||
"added": {},
|
||||
"removed": {},
|
||||
"updated": {},
|
||||
"updated": {
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"angle": 0,
|
||||
"backgroundColor": "transparent",
|
||||
"boundElements": null,
|
||||
"customData": undefined,
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [
|
||||
"A",
|
||||
],
|
||||
"height": 100,
|
||||
"index": "a0",
|
||||
"isDeleted": true,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 5,
|
||||
"width": 100,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 4,
|
||||
},
|
||||
},
|
||||
"id1": {
|
||||
"deleted": {
|
||||
"angle": 0,
|
||||
"backgroundColor": "transparent",
|
||||
"boundElements": null,
|
||||
"customData": undefined,
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [
|
||||
"A",
|
||||
],
|
||||
"height": 100,
|
||||
"index": "a1",
|
||||
"isDeleted": true,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 5,
|
||||
"width": 100,
|
||||
"x": 100,
|
||||
"y": 100,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": "id13",
|
||||
},
|
||||
@@ -6072,7 +6178,7 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 8,
|
||||
"version": 9,
|
||||
"width": 10,
|
||||
"x": 20,
|
||||
"y": 0,
|
||||
@@ -6102,7 +6208,7 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 8,
|
||||
"version": 9,
|
||||
"width": 10,
|
||||
"x": 50,
|
||||
"y": 50,
|
||||
@@ -6187,7 +6293,39 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"elements": {
|
||||
"added": {},
|
||||
"removed": {},
|
||||
"updated": {},
|
||||
"updated": {
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"angle": 0,
|
||||
"backgroundColor": "transparent",
|
||||
"boundElements": null,
|
||||
"customData": undefined,
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 10,
|
||||
"index": "a1",
|
||||
"isDeleted": true,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 8,
|
||||
"width": 10,
|
||||
"x": 20,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 7,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": "id18",
|
||||
},
|
||||
@@ -6205,11 +6343,11 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"backgroundColor": "#ffc9c9",
|
||||
"version": 8,
|
||||
"version": 9,
|
||||
},
|
||||
"inserted": {
|
||||
"backgroundColor": "transparent",
|
||||
"version": 7,
|
||||
"version": 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -6234,7 +6372,39 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"elements": {
|
||||
"added": {},
|
||||
"removed": {},
|
||||
"updated": {},
|
||||
"updated": {
|
||||
"id8": {
|
||||
"deleted": {
|
||||
"angle": 0,
|
||||
"backgroundColor": "#ffc9c9",
|
||||
"boundElements": null,
|
||||
"customData": undefined,
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 10,
|
||||
"index": "a2",
|
||||
"isDeleted": true,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 8,
|
||||
"width": 10,
|
||||
"x": 30,
|
||||
"y": 30,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 7,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": "id20",
|
||||
},
|
||||
@@ -6251,12 +6421,12 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"updated": {
|
||||
"id8": {
|
||||
"deleted": {
|
||||
"version": 8,
|
||||
"version": 9,
|
||||
"x": 50,
|
||||
"y": 50,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 7,
|
||||
"version": 8,
|
||||
"x": 30,
|
||||
"y": 30,
|
||||
},
|
||||
@@ -7104,7 +7274,7 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"strokeWidth": 2,
|
||||
"type": "arrow",
|
||||
"updated": 1,
|
||||
"version": 8,
|
||||
"version": 9,
|
||||
"width": 10,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
@@ -7135,7 +7305,60 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"elements": {
|
||||
"added": {},
|
||||
"removed": {},
|
||||
"updated": {},
|
||||
"updated": {
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"angle": 0,
|
||||
"backgroundColor": "transparent",
|
||||
"boundElements": null,
|
||||
"customData": undefined,
|
||||
"elbowed": false,
|
||||
"endArrowhead": "arrow",
|
||||
"endBinding": null,
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 10,
|
||||
"index": "a0",
|
||||
"isDeleted": true,
|
||||
"lastCommittedPoint": [
|
||||
10,
|
||||
10,
|
||||
],
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"opacity": 100,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
],
|
||||
[
|
||||
10,
|
||||
10,
|
||||
],
|
||||
],
|
||||
"roughness": 1,
|
||||
"roundness": {
|
||||
"type": 2,
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"startBinding": null,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "arrow",
|
||||
"version": 9,
|
||||
"width": 10,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": "id13",
|
||||
},
|
||||
@@ -7344,7 +7567,7 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 8,
|
||||
"version": 9,
|
||||
"width": 10,
|
||||
"x": 10,
|
||||
"y": 0,
|
||||
@@ -7375,7 +7598,39 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"elements": {
|
||||
"added": {},
|
||||
"removed": {},
|
||||
"updated": {},
|
||||
"updated": {
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"angle": 0,
|
||||
"backgroundColor": "transparent",
|
||||
"boundElements": null,
|
||||
"customData": undefined,
|
||||
"fillStyle": "solid",
|
||||
"frameId": null,
|
||||
"groupIds": [],
|
||||
"height": 10,
|
||||
"index": "a0",
|
||||
"isDeleted": true,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 8,
|
||||
"width": 10,
|
||||
"x": 10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 7,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": "id7",
|
||||
},
|
||||
@@ -7393,11 +7648,11 @@ exports[`history > multiplayer undo/redo > should iterate through the history wh
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"backgroundColor": "#ffec99",
|
||||
"version": 8,
|
||||
"version": 9,
|
||||
},
|
||||
"inserted": {
|
||||
"backgroundColor": "transparent",
|
||||
"version": 7,
|
||||
"version": 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -10326,7 +10581,7 @@ exports[`history > multiplayer undo/redo > should redistribute deltas when eleme
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 8,
|
||||
"version": 9,
|
||||
"width": 10,
|
||||
"x": 10,
|
||||
"y": 0,
|
||||
@@ -10409,7 +10664,18 @@ exports[`history > multiplayer undo/redo > should redistribute deltas when eleme
|
||||
"elements": {
|
||||
"added": {},
|
||||
"removed": {},
|
||||
"updated": {},
|
||||
"updated": {
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"isDeleted": false,
|
||||
"version": 9,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": false,
|
||||
"version": 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": "id8",
|
||||
},
|
||||
@@ -15775,6 +16041,14 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 5,
|
||||
},
|
||||
},
|
||||
"id1": {
|
||||
"deleted": {
|
||||
"version": 5,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 4,
|
||||
},
|
||||
},
|
||||
"id2": {
|
||||
"deleted": {
|
||||
"boundElements": [
|
||||
@@ -16736,6 +17010,14 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 5,
|
||||
},
|
||||
},
|
||||
"id1": {
|
||||
"deleted": {
|
||||
"version": 6,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 5,
|
||||
},
|
||||
},
|
||||
"id2": {
|
||||
"deleted": {
|
||||
"boundElements": [
|
||||
@@ -17361,6 +17643,14 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 9,
|
||||
},
|
||||
},
|
||||
"id1": {
|
||||
"deleted": {
|
||||
"version": 10,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 9,
|
||||
},
|
||||
},
|
||||
"id2": {
|
||||
"deleted": {
|
||||
"boundElements": [
|
||||
@@ -17722,6 +18012,14 @@ exports[`history > singleplayer undo/redo > should support bidirectional binding
|
||||
"version": 7,
|
||||
},
|
||||
},
|
||||
"id2": {
|
||||
"deleted": {
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": "id21",
|
||||
|
@@ -2216,7 +2216,16 @@ exports[`regression tests > alt-drag duplicates an element > [end of test] undo
|
||||
},
|
||||
},
|
||||
},
|
||||
"updated": {},
|
||||
"updated": {
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"version": 5,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": "id6",
|
||||
},
|
||||
@@ -10892,7 +10901,32 @@ exports[`regression tests > make a group and duplicate it > [end of test] undo s
|
||||
},
|
||||
},
|
||||
},
|
||||
"updated": {},
|
||||
"updated": {
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"version": 6,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 4,
|
||||
},
|
||||
},
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"version": 6,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 4,
|
||||
},
|
||||
},
|
||||
"id6": {
|
||||
"deleted": {
|
||||
"version": 6,
|
||||
},
|
||||
"inserted": {
|
||||
"version": 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"id": "id21",
|
||||
},
|
||||
|
@@ -4055,7 +4055,7 @@ describe("history", () => {
|
||||
expect.objectContaining({
|
||||
id: container.id,
|
||||
boundElements: [{ id: remoteText.id, type: "text" }],
|
||||
isDeleted: true,
|
||||
isDeleted: false,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: text.id,
|
||||
@@ -4064,8 +4064,7 @@ describe("history", () => {
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: remoteText.id,
|
||||
// unbound
|
||||
containerId: null,
|
||||
containerId: container.id,
|
||||
isDeleted: false,
|
||||
}),
|
||||
]);
|
||||
|
@@ -1,82 +0,0 @@
|
||||
import { defineConfig, devices } from "@playwright/test";
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
// import dotenv from 'dotenv';
|
||||
// import path from 'path';
|
||||
// dotenv.config({ path: path.resolve(__dirname, '.env') });
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: "./excalidraw-app/tests/regression",
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 1,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: "html",
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
actionTimeout: 0,
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: "http://localhost:3000",
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
headless: true,
|
||||
},
|
||||
timeout: 1200000,
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: { ...devices["Desktop Chrome"] },
|
||||
},
|
||||
|
||||
// {
|
||||
// name: "firefox",
|
||||
// use: { ...devices["Desktop Firefox"] },
|
||||
// },
|
||||
|
||||
// {
|
||||
// name: "webkit",
|
||||
// use: { ...devices["Desktop Safari"] },
|
||||
// },
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
// {
|
||||
// name: 'Mobile Chrome',
|
||||
// use: { ...devices['Pixel 5'] },
|
||||
// },
|
||||
// {
|
||||
// name: 'Mobile Safari',
|
||||
// use: { ...devices['iPhone 12'] },
|
||||
// },
|
||||
|
||||
/* Test against branded browsers. */
|
||||
// {
|
||||
// name: 'Microsoft Edge',
|
||||
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
||||
// },
|
||||
// {
|
||||
// name: 'Google Chrome',
|
||||
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
||||
// },
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
command: "yarn start --no-open",
|
||||
url: "http://localhost:3000",
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
});
|
72
yarn.lock
72
yarn.lock
@@ -1452,14 +1452,15 @@
|
||||
resolved "https://registry.yarnpkg.com/@excalidraw/markdown-to-text/-/markdown-to-text-0.1.2.tgz#1703705e7da608cf478f17bfe96fb295f55a23eb"
|
||||
integrity sha512-1nDXBNAojfi3oSFwJswKREkFm5wrSjqay81QlyRv2pkITG/XYB5v+oChENVBQLcxQwX4IUATWvXM5BcaNhPiIg==
|
||||
|
||||
"@excalidraw/mermaid-to-excalidraw@1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@excalidraw/mermaid-to-excalidraw/-/mermaid-to-excalidraw-1.1.2.tgz#74d9507971976a7d3d960a1b2e8fb49a9f1f0d22"
|
||||
integrity sha512-hAFv/TTIsOdoy0dL5v+oBd297SQ+Z88gZ5u99fCIFuEMHfQuPgLhU/ztKhFSTs7fISwVo6fizny/5oQRR3d4tQ==
|
||||
"@excalidraw/mermaid-to-excalidraw@1.1.3":
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@excalidraw/mermaid-to-excalidraw/-/mermaid-to-excalidraw-1.1.3.tgz#3204642c99f3d49c2ad41108217a5d493ef7fd09"
|
||||
integrity sha512-/50GUWlGotc+FCMX7nM1P1kWm9vNd3fuq38v7upBp9IHqlw6Zmfyj79eG/0vz1heifuYrSW9yzzv0q9jVALzxg==
|
||||
dependencies:
|
||||
"@excalidraw/markdown-to-text" "0.1.2"
|
||||
mermaid "10.9.3"
|
||||
mermaid "10.9.4"
|
||||
nanoid "4.0.2"
|
||||
react-split "^2.0.14"
|
||||
|
||||
"@excalidraw/prettier-config@1.0.2":
|
||||
version "1.0.2"
|
||||
@@ -2162,13 +2163,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
|
||||
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
|
||||
|
||||
"@playwright/test@1.55.0":
|
||||
version "1.55.0"
|
||||
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.55.0.tgz#080fa6d9ee6d749ff523b1c18259572d0268b963"
|
||||
integrity sha512-04IXzPwHrW69XusN/SIdDdKZBzMfOT9UNT/YiJit/xpy2VuAoB8NHc8Aplb96zsWDddLnbkPL3TsmrS04ZU2xQ==
|
||||
dependencies:
|
||||
playwright "1.55.0"
|
||||
|
||||
"@polka/url@^1.0.0-next.24":
|
||||
version "1.0.0-next.28"
|
||||
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.28.tgz#d45e01c4a56f143ee69c54dd6b12eade9e270a73"
|
||||
@@ -2952,13 +2946,6 @@
|
||||
dependencies:
|
||||
undici-types "~6.20.0"
|
||||
|
||||
"@types/node@24.3.0":
|
||||
version "24.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-24.3.0.tgz#89b09f45cb9a8ee69466f18ee5864e4c3eb84dec"
|
||||
integrity sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==
|
||||
dependencies:
|
||||
undici-types "~7.10.0"
|
||||
|
||||
"@types/node@>=12.12.47", "@types/node@>=13.7.0":
|
||||
version "22.13.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.8.tgz#57e2450295b33a6518d6fd4f65f47236d3e41d8d"
|
||||
@@ -5840,11 +5827,6 @@ fs.realpath@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
||||
|
||||
fsevents@2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||
|
||||
fsevents@~2.3.2, fsevents@~2.3.3:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
||||
@@ -7076,10 +7058,10 @@ merge2@^1.3.0, merge2@^1.4.1:
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
mermaid@10.9.3:
|
||||
version "10.9.3"
|
||||
resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-10.9.3.tgz#90bc6f15c33dbe5d9507fed31592cc0d88fee9f7"
|
||||
integrity sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw==
|
||||
mermaid@10.9.4:
|
||||
version "10.9.4"
|
||||
resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-10.9.4.tgz#985fd4b6d73ae795b87f0b32f620a56d3d6bf1f8"
|
||||
integrity sha512-VIG2B0R9ydvkS+wShA8sXqkzfpYglM2Qwj7VyUeqzNVqSGPoP/tcaUr3ub4ESykv8eqQJn3p99bHNvYdg3gCHQ==
|
||||
dependencies:
|
||||
"@braintree/sanitize-url" "^6.0.1"
|
||||
"@types/d3-scale" "^4.0.3"
|
||||
@@ -7857,20 +7839,6 @@ pkg-dir@4.2.0:
|
||||
dependencies:
|
||||
find-up "^4.0.0"
|
||||
|
||||
playwright-core@1.55.0:
|
||||
version "1.55.0"
|
||||
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.55.0.tgz#ec8a9f8ef118afb3e86e0f46f1393e3bea32adf4"
|
||||
integrity sha512-GvZs4vU3U5ro2nZpeiwyb0zuFaqb9sUiAJuyrWpcGouD8y9/HLgGbNRjIph7zU9D3hnPaisMl9zG9CgFi/biIg==
|
||||
|
||||
playwright@1.55.0:
|
||||
version "1.55.0"
|
||||
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.55.0.tgz#7aca7ac3ffd9e083a8ad8b2514d6f9ba401cc78b"
|
||||
integrity sha512-sdCWStblvV1YU909Xqx0DhOjPZE4/5lJsIS84IfN9dAZfcl/CIZ5O8l3o0j7hPMjDvqoTF8ZUcc+i/GL5erstA==
|
||||
dependencies:
|
||||
playwright-core "1.55.0"
|
||||
optionalDependencies:
|
||||
fsevents "2.3.2"
|
||||
|
||||
png-chunk-text@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/png-chunk-text/-/png-chunk-text-1.0.0.tgz#1c6006d8e34ba471d38e1c9c54b3f53e1085e18f"
|
||||
@@ -7996,7 +7964,7 @@ progress@2.0.3, progress@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||
|
||||
prop-types@^15.8.1:
|
||||
prop-types@^15.5.7, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
@@ -8141,6 +8109,14 @@ react-remove-scroll@^2.6.3:
|
||||
use-callback-ref "^1.3.3"
|
||||
use-sidecar "^1.1.3"
|
||||
|
||||
react-split@^2.0.14:
|
||||
version "2.0.14"
|
||||
resolved "https://registry.yarnpkg.com/react-split/-/react-split-2.0.14.tgz#ef198259bf43264d605f792fb3384f15f5b34432"
|
||||
integrity sha512-bKWydgMgaKTg/2JGQnaJPg51T6dmumTWZppFgEbbY0Fbme0F5TuatAScCLaqommbGQQf/ZT1zaejuPDriscISA==
|
||||
dependencies:
|
||||
prop-types "^15.5.7"
|
||||
split.js "^1.6.0"
|
||||
|
||||
react-style-singleton@^2.2.2, react-style-singleton@^2.2.3:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.3.tgz#4265608be69a4d70cfe3047f2c6c88b2c3ace388"
|
||||
@@ -8780,6 +8756,11 @@ sourcemap-codec@^1.4.8:
|
||||
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
||||
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
|
||||
|
||||
split.js@^1.6.0:
|
||||
version "1.6.5"
|
||||
resolved "https://registry.yarnpkg.com/split.js/-/split.js-1.6.5.tgz#f7f61da1044c9984cb42947df4de4fadb5a3f300"
|
||||
integrity sha512-mPTnGCiS/RiuTNsVhCm9De9cCAUsrNFFviRbADdKiiV+Kk8HKp/0fWu7Kr8pi3/yBmsqLFHuXGT9UUZ+CNLwFw==
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
@@ -9361,11 +9342,6 @@ undici-types@~6.20.0:
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
|
||||
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
|
||||
|
||||
undici-types@~7.10.0:
|
||||
version "7.10.0"
|
||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.10.0.tgz#4ac2e058ce56b462b056e629cc6a02393d3ff350"
|
||||
integrity sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==
|
||||
|
||||
unicode-canonical-property-names-ecmascript@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2"
|
||||
|
Reference in New Issue
Block a user