mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
Merge branch 'staging-render' into develop
This commit is contained in:
58
frontend/playwright/data/text-editor/get-file-blank.json
Normal file
58
frontend/playwright/data/text-editor/get-file-blank.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"~:features": {
|
||||
"~#set": [
|
||||
"layout/grid",
|
||||
"styles/v2",
|
||||
"fdata/pointer-map",
|
||||
"fdata/objects-map",
|
||||
"components/v2",
|
||||
"fdata/shape-data-type"
|
||||
]
|
||||
},
|
||||
"~:permissions": {
|
||||
"~:type": "~:membership",
|
||||
"~:is-owner": true,
|
||||
"~:is-admin": true,
|
||||
"~:can-edit": true,
|
||||
"~:can-read": true,
|
||||
"~:is-logged": true
|
||||
},
|
||||
"~:has-media-trimmed": false,
|
||||
"~:comment-thread-seqn": 0,
|
||||
"~:name": "New File 1",
|
||||
"~:revn": 11,
|
||||
"~:modified-at": "~m1713873823633",
|
||||
"~:id": "~uc7ce0794-0992-8105-8004-38f280443849",
|
||||
"~:is-shared": false,
|
||||
"~:version": 46,
|
||||
"~:project-id": "~uc7ce0794-0992-8105-8004-38e630f7920b",
|
||||
"~:created-at": "~m1713536343369",
|
||||
"~:data": {
|
||||
"~:pages": [
|
||||
"~u66697432-c33d-8055-8006-2c62cc084cad"
|
||||
],
|
||||
"~:pages-index": {
|
||||
"~u66697432-c33d-8055-8006-2c62cc084cad": {
|
||||
"~#penpot/pointer": [
|
||||
"~ude58c8f6-c5c2-8196-8004-3df9e2e52d88",
|
||||
{
|
||||
"~:created-at": "~m1713873823636"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"~:id": "~uc7ce0794-0992-8105-8004-38f280443849",
|
||||
"~:options": {
|
||||
"~:components-v2": true
|
||||
},
|
||||
"~:recent-colors": [
|
||||
{
|
||||
"~:color": "#0000ff",
|
||||
"~:opacity": 1,
|
||||
"~:id": null,
|
||||
"~:file-id": null,
|
||||
"~:image": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
345
frontend/playwright/data/text-editor/get-file-lorem-ipsum.json
Normal file
345
frontend/playwright/data/text-editor/get-file-lorem-ipsum.json
Normal file
@@ -0,0 +1,345 @@
|
||||
{
|
||||
"~:features": {
|
||||
"~#set": [
|
||||
"fdata/path-data",
|
||||
"plugins/runtime",
|
||||
"design-tokens/v1",
|
||||
"layout/grid",
|
||||
"styles/v2",
|
||||
"fdata/pointer-map",
|
||||
"fdata/objects-map",
|
||||
"components/v2",
|
||||
"fdata/shape-data-type",
|
||||
"text-editor/v2"
|
||||
]
|
||||
},
|
||||
"~:team-id": "~u9e6e22b2-db76-81d6-8006-75d7cdbb8bad",
|
||||
"~:permissions": {
|
||||
"~:type": "~:membership",
|
||||
"~:is-owner": true,
|
||||
"~:is-admin": true,
|
||||
"~:can-edit": true,
|
||||
"~:can-read": true,
|
||||
"~:is-logged": true
|
||||
},
|
||||
"~:has-media-trimmed": false,
|
||||
"~:comment-thread-seqn": 0,
|
||||
"~:name": "Bug 11552",
|
||||
"~:revn": 3,
|
||||
"~:modified-at": "~m1753957736516",
|
||||
"~:vern": 0,
|
||||
"~:id": "~u238a17e0-75ff-8075-8006-934586ea2230",
|
||||
"~:is-shared": false,
|
||||
"~:migrations": {
|
||||
"~#ordered-set": [
|
||||
"legacy-2",
|
||||
"legacy-3",
|
||||
"legacy-5",
|
||||
"legacy-6",
|
||||
"legacy-7",
|
||||
"legacy-8",
|
||||
"legacy-9",
|
||||
"legacy-10",
|
||||
"legacy-11",
|
||||
"legacy-12",
|
||||
"legacy-13",
|
||||
"legacy-14",
|
||||
"legacy-16",
|
||||
"legacy-17",
|
||||
"legacy-18",
|
||||
"legacy-19",
|
||||
"legacy-25",
|
||||
"legacy-26",
|
||||
"legacy-27",
|
||||
"legacy-28",
|
||||
"legacy-29",
|
||||
"legacy-31",
|
||||
"legacy-32",
|
||||
"legacy-33",
|
||||
"legacy-34",
|
||||
"legacy-36",
|
||||
"legacy-37",
|
||||
"legacy-38",
|
||||
"legacy-39",
|
||||
"legacy-40",
|
||||
"legacy-41",
|
||||
"legacy-42",
|
||||
"legacy-43",
|
||||
"legacy-44",
|
||||
"legacy-45",
|
||||
"legacy-46",
|
||||
"legacy-47",
|
||||
"legacy-48",
|
||||
"legacy-49",
|
||||
"legacy-50",
|
||||
"legacy-51",
|
||||
"legacy-52",
|
||||
"legacy-53",
|
||||
"legacy-54",
|
||||
"legacy-55",
|
||||
"legacy-56",
|
||||
"legacy-57",
|
||||
"legacy-59",
|
||||
"legacy-62",
|
||||
"legacy-65",
|
||||
"legacy-66",
|
||||
"legacy-67",
|
||||
"0001-remove-tokens-from-groups",
|
||||
"0002-normalize-bool-content-v2",
|
||||
"0002-clean-shape-interactions",
|
||||
"0003-fix-root-shape",
|
||||
"0003-convert-path-content-v2",
|
||||
"0004-clean-shadow-color",
|
||||
"0005-deprecate-image-type",
|
||||
"0006-fix-old-texts-fills",
|
||||
"0007-clear-invalid-strokes-and-fills-v2",
|
||||
"0008-fix-library-colors-v4",
|
||||
"0009-clean-library-colors",
|
||||
"0009-add-partial-text-touched-flags"
|
||||
]
|
||||
},
|
||||
"~:version": 67,
|
||||
"~:project-id": "~u9e6e22b2-db76-81d6-8006-75d7cdc30669",
|
||||
"~:created-at": "~m1753957644225",
|
||||
"~:data": {
|
||||
"~:pages": ["~u238a17e0-75ff-8075-8006-934586ea2231"],
|
||||
"~:pages-index": {
|
||||
"~u238a17e0-75ff-8075-8006-934586ea2231": {
|
||||
"~:objects": {
|
||||
"~u00000000-0000-0000-0000-000000000000": {
|
||||
"~#shape": {
|
||||
"~:y": 0,
|
||||
"~:hide-fill-on-export": false,
|
||||
"~:transform": {
|
||||
"~#matrix": {
|
||||
"~:a": 1.0,
|
||||
"~:b": 0.0,
|
||||
"~:c": 0.0,
|
||||
"~:d": 1.0,
|
||||
"~:e": 0.0,
|
||||
"~:f": 0.0
|
||||
}
|
||||
},
|
||||
"~:rotation": 0,
|
||||
"~:name": "Root Frame",
|
||||
"~:width": 0.01,
|
||||
"~:type": "~:frame",
|
||||
"~:points": [
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 0.0,
|
||||
"~:y": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 0.01,
|
||||
"~:y": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 0.01,
|
||||
"~:y": 0.01
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 0.0,
|
||||
"~:y": 0.01
|
||||
}
|
||||
}
|
||||
],
|
||||
"~:r2": 0,
|
||||
"~:proportion-lock": false,
|
||||
"~:transform-inverse": {
|
||||
"~#matrix": {
|
||||
"~:a": 1.0,
|
||||
"~:b": 0.0,
|
||||
"~:c": 0.0,
|
||||
"~:d": 1.0,
|
||||
"~:e": 0.0,
|
||||
"~:f": 0.0
|
||||
}
|
||||
},
|
||||
"~:r3": 0,
|
||||
"~:r1": 0,
|
||||
"~:id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:parent-id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:frame-id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:strokes": [],
|
||||
"~:x": 0,
|
||||
"~:proportion": 1.0,
|
||||
"~:r4": 0,
|
||||
"~:selrect": {
|
||||
"~#rect": {
|
||||
"~:x": 0,
|
||||
"~:y": 0,
|
||||
"~:width": 0.01,
|
||||
"~:height": 0.01,
|
||||
"~:x1": 0,
|
||||
"~:y1": 0,
|
||||
"~:x2": 0.01,
|
||||
"~:y2": 0.01
|
||||
}
|
||||
},
|
||||
"~:fills": [
|
||||
{
|
||||
"~:fill-color": "#FFFFFF",
|
||||
"~:fill-opacity": 1
|
||||
}
|
||||
],
|
||||
"~:flip-x": null,
|
||||
"~:height": 0.01,
|
||||
"~:flip-y": null,
|
||||
"~:shapes": ["~ucc6f0580-449c-8019-8006-9345db077fa0"]
|
||||
}
|
||||
},
|
||||
"~ucc6f0580-449c-8019-8006-9345db077fa0": {
|
||||
"~#shape": {
|
||||
"~:y": 438,
|
||||
"~:transform": {
|
||||
"~#matrix": {
|
||||
"~:a": 1.0,
|
||||
"~:b": 0.0,
|
||||
"~:c": 0.0,
|
||||
"~:d": 1.0,
|
||||
"~:e": 0.0,
|
||||
"~:f": 0.0
|
||||
}
|
||||
},
|
||||
"~:rotation": 0,
|
||||
"~:grow-type": "~:auto-width",
|
||||
"~:content": {
|
||||
"~:type": "root",
|
||||
"~:key": "1s4am1jl24s",
|
||||
"~:children": [
|
||||
{
|
||||
"~:type": "paragraph-set",
|
||||
"~:children": [
|
||||
{
|
||||
"~:line-height": "1.2",
|
||||
"~:font-style": "normal",
|
||||
"~:children": [
|
||||
{
|
||||
"~:line-height": "1.2",
|
||||
"~:font-style": "normal",
|
||||
"~:typography-ref-id": null,
|
||||
"~:text-transform": "none",
|
||||
"~:font-id": "sourcesanspro",
|
||||
"~:key": "13p0zwl2yhc",
|
||||
"~:font-size": "14",
|
||||
"~:font-weight": "400",
|
||||
"~:typography-ref-file": null,
|
||||
"~:font-variant-id": "regular",
|
||||
"~:text-decoration": "none",
|
||||
"~:letter-spacing": "0",
|
||||
"~:fills": [
|
||||
{
|
||||
"~:fill-color": "#000000",
|
||||
"~:fill-opacity": 1
|
||||
}
|
||||
],
|
||||
"~:font-family": "sourcesanspro",
|
||||
"~:text": "Lorem ipsum"
|
||||
}
|
||||
],
|
||||
"~:typography-ref-id": null,
|
||||
"~:text-transform": "none",
|
||||
"~:text-align": "left",
|
||||
"~:font-id": "sourcesanspro",
|
||||
"~:key": "20hf3kmyoub",
|
||||
"~:font-size": "14",
|
||||
"~:font-weight": "400",
|
||||
"~:typography-ref-file": null,
|
||||
"~:text-direction": "ltr",
|
||||
"~:type": "paragraph",
|
||||
"~:font-variant-id": "regular",
|
||||
"~:text-decoration": "none",
|
||||
"~:letter-spacing": "0",
|
||||
"~:fills": [
|
||||
{
|
||||
"~:fill-color": "#000000",
|
||||
"~:fill-opacity": 1
|
||||
}
|
||||
],
|
||||
"~:font-family": "sourcesanspro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"~:vertical-align": "top"
|
||||
},
|
||||
"~:hide-in-viewer": false,
|
||||
"~:name": "Lorem ipsum",
|
||||
"~:width": 77,
|
||||
"~:type": "~:text",
|
||||
"~:points": [
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 404,
|
||||
"~:y": 438
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 481,
|
||||
"~:y": 438
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 481,
|
||||
"~:y": 455
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 404,
|
||||
"~:y": 455
|
||||
}
|
||||
}
|
||||
],
|
||||
"~:transform-inverse": {
|
||||
"~#matrix": {
|
||||
"~:a": 1.0,
|
||||
"~:b": 0.0,
|
||||
"~:c": 0.0,
|
||||
"~:d": 1.0,
|
||||
"~:e": 0.0,
|
||||
"~:f": 0.0
|
||||
}
|
||||
},
|
||||
"~:id": "~ucc6f0580-449c-8019-8006-9345db077fa0",
|
||||
"~:parent-id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:frame-id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:x": 404,
|
||||
"~:selrect": {
|
||||
"~#rect": {
|
||||
"~:x": 404,
|
||||
"~:y": 438,
|
||||
"~:width": 77,
|
||||
"~:height": 17,
|
||||
"~:x1": 404,
|
||||
"~:y1": 438,
|
||||
"~:x2": 481,
|
||||
"~:y2": 455
|
||||
}
|
||||
},
|
||||
"~:flip-x": null,
|
||||
"~:height": 17,
|
||||
"~:flip-y": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"~:id": "~u238a17e0-75ff-8075-8006-934586ea2231",
|
||||
"~:name": "Page 1"
|
||||
}
|
||||
},
|
||||
"~:id": "~u238a17e0-75ff-8075-8006-934586ea2230",
|
||||
"~:options": {
|
||||
"~:components-v2": true,
|
||||
"~:base-font-size": "16px"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1 @@
|
||||
{
|
||||
"~:revn": 2,
|
||||
"~:lagged": []
|
||||
|
||||
}
|
||||
w
|
||||
|
||||
4
frontend/playwright/data/text-editor/update-file.json
Normal file
4
frontend/playwright/data/text-editor/update-file.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"~:revn": 2,
|
||||
"~:lagged": []
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
[
|
||||
{
|
||||
"~:id": "~u088df3d4-d383-80f6-8004-527e50ea4f1f",
|
||||
"~:revn": 21,
|
||||
"~:file-id": "~uc7ce0794-0992-8105-8004-38f280443849",
|
||||
"~:session-id": "~u1dc6d4fa-7bd3-803a-8004-527dd9df2c62",
|
||||
"~:changes": []
|
||||
}
|
||||
]
|
||||
36
frontend/playwright/helpers/Clipboard.js
Normal file
36
frontend/playwright/helpers/Clipboard.js
Normal file
@@ -0,0 +1,36 @@
|
||||
export class Clipboard {
|
||||
static Permission = {
|
||||
ONLY_READ: ['clipboard-read'],
|
||||
ONLY_WRITE: ['clipboard-write'],
|
||||
ALL: ['clipboard-read', 'clipboard-write']
|
||||
}
|
||||
|
||||
static enable(context, permissions) {
|
||||
return context.grantPermissions(permissions)
|
||||
}
|
||||
|
||||
static writeText(page, text) {
|
||||
return page.evaluate((text) => navigator.clipboard.writeText(text), text);
|
||||
}
|
||||
|
||||
static readText(page) {
|
||||
return page.evaluate(() => navigator.clipboard.readText());
|
||||
}
|
||||
|
||||
constructor(page, context) {
|
||||
this.page = page
|
||||
this.context = context
|
||||
}
|
||||
|
||||
enable(permissions) {
|
||||
return Clipboard.enable(this.context, permissions);
|
||||
}
|
||||
|
||||
writeText(text) {
|
||||
return Clipboard.writeText(this.page, text);
|
||||
}
|
||||
|
||||
readText() {
|
||||
return Clipboard.readText(this.page);
|
||||
}
|
||||
}
|
||||
30
frontend/playwright/helpers/Transit.js
Normal file
30
frontend/playwright/helpers/Transit.js
Normal file
@@ -0,0 +1,30 @@
|
||||
export class Transit {
|
||||
static parse(value) {
|
||||
if (typeof value !== 'string')
|
||||
return value
|
||||
|
||||
if (value.startsWith('~'))
|
||||
return value.slice(2)
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
static get(object, ...path) {
|
||||
let aux = object;
|
||||
for (const name of path) {
|
||||
if (typeof name !== 'string') {
|
||||
if (!(name in aux)) {
|
||||
return undefined;
|
||||
}
|
||||
aux = aux[name];
|
||||
} else {
|
||||
const transitName = `~:${name}`;
|
||||
if (!(transitName in aux)) {
|
||||
return undefined;
|
||||
}
|
||||
aux = aux[transitName];
|
||||
}
|
||||
}
|
||||
return this.parse(aux);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,27 @@
|
||||
export class BasePage {
|
||||
/**
|
||||
* Mocks multiple RPC calls in a single call.
|
||||
*
|
||||
* @param {Page} page
|
||||
* @param {object<string, string>} paths
|
||||
* @param {*} options
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async mockRPCs(page, paths, options) {
|
||||
for (const [path, jsonFilename] of Object.entries(paths)) {
|
||||
await this.mockRPC(page, path, jsonFilename, options)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks an RPC call using a file.
|
||||
*
|
||||
* @param {Page} page
|
||||
* @param {string} path
|
||||
* @param {string} jsonFilename
|
||||
* @param {*} options
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async mockRPC(page, path, jsonFilename, options) {
|
||||
if (!page) {
|
||||
throw new TypeError("Invalid page argument. Must be a Playwright page.");
|
||||
@@ -93,6 +116,10 @@ export class BasePage {
|
||||
return this.#page;
|
||||
}
|
||||
|
||||
async mockRPCs(paths, options) {
|
||||
return BasePage.mockRPCs(this.page, paths, options);
|
||||
}
|
||||
|
||||
async mockRPC(path, jsonFilename, options) {
|
||||
return BasePage.mockRPC(this.page, path, jsonFilename, options);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,146 @@
|
||||
import { expect } from "@playwright/test";
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { BaseWebSocketPage } from "./BaseWebSocketPage";
|
||||
import { Transit } from '../../helpers/Transit';
|
||||
|
||||
export class WorkspacePage extends BaseWebSocketPage {
|
||||
static TextEditor = class TextEditor {
|
||||
constructor(workspacePage) {
|
||||
this.workspacePage = workspacePage;
|
||||
|
||||
// locators.
|
||||
this.fontSize = this.workspacePage.rightSidebar.getByRole("textbox", {
|
||||
name: "Font Size",
|
||||
});
|
||||
this.lineHeight = this.workspacePage.rightSidebar.getByRole("textbox", {
|
||||
name: "Line Height",
|
||||
});
|
||||
this.letterSpacing = this.workspacePage.rightSidebar.getByRole(
|
||||
"textbox",
|
||||
{
|
||||
name: "Letter Spacing",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
get page() {
|
||||
return this.workspacePage.page;
|
||||
}
|
||||
|
||||
async waitForStyle(locator, styleName) {
|
||||
return locator.evaluate(
|
||||
(element, styleName) => element.style.getPropertyValue(styleName),
|
||||
styleName,
|
||||
);
|
||||
}
|
||||
|
||||
async waitForEditor() {
|
||||
return this.page.waitForSelector('[data-itype="editor"]');
|
||||
}
|
||||
|
||||
async waitForRoot() {
|
||||
return this.page.waitForSelector('[data-itype="root"]');
|
||||
}
|
||||
|
||||
async waitForParagraph(nth) {
|
||||
if (!nth) {
|
||||
return this.page.waitForSelector('[data-itype="paragraph"]');
|
||||
}
|
||||
return this.page.waitForSelector(
|
||||
`[data-itype="paragraph"]:nth-child(${nth})`,
|
||||
);
|
||||
}
|
||||
|
||||
async waitForParagraphStyle(nth, styleName) {
|
||||
const paragraph = await this.waitForParagraph(nth);
|
||||
return this.waitForStyle(paragraph, styleName);
|
||||
}
|
||||
|
||||
async waitForTextSpan(nth = 0) {
|
||||
if (!nth) {
|
||||
return this.page.waitForSelector('[data-itype="inline"]');
|
||||
}
|
||||
return this.page.waitForSelector(
|
||||
`[data-itype="inline"]:nth-child(${nth})`,
|
||||
);
|
||||
}
|
||||
|
||||
async waitForTextSpanContent(nth = 0) {
|
||||
const textSpan = await this.waitForTextSpan(nth);
|
||||
const textContent = await textSpan.textContent();
|
||||
return textContent;
|
||||
}
|
||||
|
||||
async waitForTextSpanStyle(nth, styleName) {
|
||||
const textSpan = await this.waitForTextSpan(nth);
|
||||
return this.waitForStyle(textSpan, styleName);
|
||||
}
|
||||
|
||||
async startEditing() {
|
||||
await this.page.keyboard.press("Enter");
|
||||
return this.waitForEditor();
|
||||
}
|
||||
|
||||
stopEditing() {
|
||||
return this.page.keyboard.press("Escape");
|
||||
}
|
||||
|
||||
async moveToLeft(amount = 0) {
|
||||
for (let i = 0; i < amount; i++) {
|
||||
await this.page.keyboard.press("ArrowLeft");
|
||||
}
|
||||
}
|
||||
|
||||
async moveToRight(amount = 0) {
|
||||
for (let i = 0; i < amount; i++) {
|
||||
await this.page.keyboard.press("ArrowRight");
|
||||
}
|
||||
}
|
||||
|
||||
async moveFromStart(offset = 0) {
|
||||
await this.page.keyboard.press("ArrowLeft");
|
||||
await this.moveToRight(offset);
|
||||
}
|
||||
|
||||
async moveFromEnd(offset = 0) {
|
||||
await this.page.keyboard.press("ArrowRight");
|
||||
await this.moveToLeft(offset);
|
||||
}
|
||||
|
||||
async selectFromStart(length, offset = 0) {
|
||||
await this.moveFromStart(offset);
|
||||
await this.page.keyboard.down("Shift");
|
||||
await this.moveToRight(length);
|
||||
await this.page.keyboard.up("Shift");
|
||||
}
|
||||
|
||||
async selectFromEnd(length, offset = 0) {
|
||||
await this.moveFromEnd(offset);
|
||||
await this.page.keyboard.down("Shift");
|
||||
await this.moveToLeft(length);
|
||||
await this.page.keyboard.up("Shift");
|
||||
}
|
||||
|
||||
async changeNumericInput(locator, newValue) {
|
||||
await expect(locator).toBeVisible();
|
||||
await locator.focus();
|
||||
await locator.fill(`${newValue}`);
|
||||
await locator.blur();
|
||||
}
|
||||
|
||||
changeFontSize(newValue) {
|
||||
return this.changeNumericInput(this.fontSize, newValue);
|
||||
}
|
||||
|
||||
changeLineHeight(newValue) {
|
||||
return this.changeNumericInput(this.lineHeight, newValue);
|
||||
}
|
||||
|
||||
changeLetterSpacing(newValue) {
|
||||
return this.changeNumericInput(this.letterSpacing, newValue);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This should be called on `test.beforeEach`.
|
||||
*
|
||||
@@ -11,50 +150,21 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||
static async init(page) {
|
||||
await BaseWebSocketPage.initWebSockets(page);
|
||||
|
||||
await BaseWebSocketPage.mockRPC(
|
||||
page,
|
||||
"get-profile",
|
||||
"logged-in-user/get-profile-logged-in.json",
|
||||
);
|
||||
await BaseWebSocketPage.mockRPC(
|
||||
page,
|
||||
"get-team-users?file-id=*",
|
||||
"logged-in-user/get-team-users-single-user.json",
|
||||
);
|
||||
await BaseWebSocketPage.mockRPC(
|
||||
page,
|
||||
"get-comment-threads?file-id=*",
|
||||
"workspace/get-comment-threads-empty.json",
|
||||
);
|
||||
await BaseWebSocketPage.mockRPC(
|
||||
page,
|
||||
"get-project?id=*",
|
||||
"workspace/get-project-default.json",
|
||||
);
|
||||
await BaseWebSocketPage.mockRPC(
|
||||
page,
|
||||
"get-team?id=*",
|
||||
"workspace/get-team-default.json",
|
||||
);
|
||||
await BaseWebSocketPage.mockRPC(page, "get-teams", "get-teams.json");
|
||||
|
||||
await BaseWebSocketPage.mockRPC(
|
||||
page,
|
||||
"get-team-members?team-id=*",
|
||||
"logged-in-user/get-team-members-your-penpot.json",
|
||||
);
|
||||
|
||||
await BaseWebSocketPage.mockRPC(
|
||||
page,
|
||||
"get-profiles-for-file-comments?file-id=*",
|
||||
"workspace/get-profile-for-file-comments.json",
|
||||
);
|
||||
|
||||
await BaseWebSocketPage.mockRPC(
|
||||
page,
|
||||
"update-profile-props",
|
||||
"workspace/update-profile-empty.json",
|
||||
);
|
||||
await BaseWebSocketPage.mockRPCs(page, {
|
||||
"get-profile": "logged-in-user/get-profile-logged-in.json",
|
||||
"get-team-users?file-id=*":
|
||||
"logged-in-user/get-team-users-single-user.json",
|
||||
"get-comment-threads?file-id=*":
|
||||
"workspace/get-comment-threads-empty.json",
|
||||
"get-project?id=*": "workspace/get-project-default.json",
|
||||
"get-team?id=*": "workspace/get-team-default.json",
|
||||
"get-teams": "get-teams.json",
|
||||
"get-team-members?team-id=*":
|
||||
"logged-in-user/get-team-members-your-penpot.json",
|
||||
"get-profiles-for-file-comments?file-id=*":
|
||||
"workspace/get-profile-for-file-comments.json",
|
||||
"update-profile-props": "workspace/update-profile-empty.json",
|
||||
});
|
||||
}
|
||||
|
||||
static anyTeamId = "c7ce0794-0992-8105-8004-38e630f7920a";
|
||||
@@ -62,9 +172,20 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||
static anyFileId = "c7ce0794-0992-8105-8004-38f280443849";
|
||||
static anyPageId = "c7ce0794-0992-8105-8004-38f28044384a";
|
||||
|
||||
/**
|
||||
* WebSocket mock
|
||||
*
|
||||
* @type {MockWebSocketHelper}
|
||||
*/
|
||||
#ws = null;
|
||||
|
||||
constructor(page) {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param {Page} page
|
||||
* @param {} [options]
|
||||
*/
|
||||
constructor(page, options) {
|
||||
super(page);
|
||||
this.pageName = page.getByTestId("page-name");
|
||||
|
||||
@@ -112,11 +233,14 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||
"tokens-context-menu-for-set",
|
||||
);
|
||||
this.contextMenuForShape = page.getByTestId("context-menu");
|
||||
if (options?.textEditor) {
|
||||
this.textEditor = new WorkspacePage.TextEditor(this);
|
||||
}
|
||||
}
|
||||
|
||||
async goToWorkspace({
|
||||
fileId = WorkspacePage.anyFileId,
|
||||
pageId = WorkspacePage.anyPageId,
|
||||
fileId = this.fileId ?? WorkspacePage.anyFileId,
|
||||
pageId = this.pageId ?? WorkspacePage.anyPageId,
|
||||
} = {}) {
|
||||
await this.page.goto(
|
||||
`/#/workspace?team-id=${WorkspacePage.anyTeamId}&file-id=${fileId}&page-id=${pageId}`,
|
||||
@@ -141,48 +265,59 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||
}
|
||||
|
||||
async setupEmptyFile() {
|
||||
await this.mockRPC(
|
||||
"get-profile",
|
||||
"logged-in-user/get-profile-logged-in.json",
|
||||
);
|
||||
await this.mockRPC(
|
||||
"get-team-users?file-id=*",
|
||||
"logged-in-user/get-team-users-single-user.json",
|
||||
);
|
||||
await this.mockRPC(
|
||||
"get-comment-threads?file-id=*",
|
||||
"workspace/get-comment-threads-empty.json",
|
||||
);
|
||||
await this.mockRPC(
|
||||
"get-project?id=*",
|
||||
"workspace/get-project-default.json",
|
||||
);
|
||||
await this.mockRPC("get-team?id=*", "workspace/get-team-default.json");
|
||||
await this.mockRPC(
|
||||
"get-profiles-for-file-comments?file-id=*",
|
||||
"workspace/get-profile-for-file-comments.json",
|
||||
);
|
||||
await this.mockRPC(/get\-file\?/, "workspace/get-file-blank.json");
|
||||
await this.mockRPC(
|
||||
"get-file-object-thumbnails?file-id=*",
|
||||
"workspace/get-file-object-thumbnails-blank.json",
|
||||
);
|
||||
await this.mockRPC(
|
||||
"get-font-variants?team-id=*",
|
||||
"workspace/get-font-variants-empty.json",
|
||||
);
|
||||
await this.mockRPC(
|
||||
"get-file-fragment?file-id=*",
|
||||
"workspace/get-file-fragment-blank.json",
|
||||
);
|
||||
await this.mockRPC(
|
||||
"get-file-libraries?file-id=*",
|
||||
"workspace/get-file-libraries-empty.json",
|
||||
);
|
||||
await this.mockRPCs({
|
||||
"get-profile": "logged-in-user/get-profile-logged-in.json",
|
||||
"get-team-users?file-id=*":
|
||||
"logged-in-user/get-team-users-single-user.json ",
|
||||
"get-comment-threads?file-id=*":
|
||||
"workspace/get-comment-threads-empty.json",
|
||||
"get-project?id=*": "workspace/get-project-default.json",
|
||||
"get-team?id=*": "workspace/get-team-default.json",
|
||||
"get-profiles-for-file-comments?file-id=*":
|
||||
"workspace/get-profile-for-file-comments.json",
|
||||
"get-file-object-thumbnails?file-id=*":
|
||||
"workspace/get-file-object-thumbnails-blank.json",
|
||||
"get-font-variants?team-id=*": "workspace/get-font-variants-empty.json",
|
||||
"get-file-fragment?file-id=*": "workspace/get-file-fragment-blank.json",
|
||||
"get-file-libraries?file-id=*": "workspace/get-file-libraries-empty.json",
|
||||
});
|
||||
|
||||
if (this.textEditor) {
|
||||
await this.mockRPC("update-file?id=*", "text-editor/update-file.json");
|
||||
}
|
||||
|
||||
// by default we mock the blank file.
|
||||
await this.mockGetFile("workspace/get-file-blank.json");
|
||||
}
|
||||
|
||||
async mockGetFile(jsonFile) {
|
||||
await this.mockRPC(/get\-file\?/, jsonFile);
|
||||
async mockGetFile(jsonFilename, options) {
|
||||
const page = this.page;
|
||||
const jsonPath = `playwright/data/${jsonFilename}`;
|
||||
const body = await readFile(jsonPath, "utf-8");
|
||||
const payload = JSON.parse(body);
|
||||
|
||||
const fileId = Transit.get(payload, "id");
|
||||
const pageId = Transit.get(payload, "data", "pages", 0);
|
||||
const teamId = Transit.get(payload, "team-id");
|
||||
|
||||
this.fileId = fileId ?? this.anyFileId;
|
||||
this.pageId = pageId ?? this.anyPageId;
|
||||
this.teamId = teamId ?? this.anyTeamId;
|
||||
|
||||
const path = /get\-file\?/;
|
||||
const url = typeof path === "string" ? `**/api/main/methods/${path}` : path;
|
||||
const interceptConfig = {
|
||||
status: 200,
|
||||
contentType: "application/transit+json",
|
||||
...options,
|
||||
};
|
||||
return page.route(url, (route) =>
|
||||
route.fulfill({
|
||||
...interceptConfig,
|
||||
body,
|
||||
}),
|
||||
);
|
||||
// await this.mockRPC(/get\-file\?/, jsonFile);
|
||||
}
|
||||
|
||||
async mockGetAsset(regex, asset) {
|
||||
@@ -190,22 +325,15 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||
}
|
||||
|
||||
async setupFileWithComments() {
|
||||
await this.mockRPC(
|
||||
"get-comment-threads?file-id=*",
|
||||
"workspace/get-comment-threads-unread.json",
|
||||
);
|
||||
await this.mockRPC(
|
||||
"get-file-fragment?file-id=*&fragment-id=*",
|
||||
"viewer/get-file-fragment-single-board.json",
|
||||
);
|
||||
await this.mockRPC(
|
||||
"get-comments?thread-id=*",
|
||||
"workspace/get-thread-comments.json",
|
||||
);
|
||||
await this.mockRPC(
|
||||
"update-comment-thread-status",
|
||||
"workspace/update-comment-thread-status.json",
|
||||
);
|
||||
await this.mockRPCs({
|
||||
"get-comment-threads?file-id=*":
|
||||
"workspace/get-comment-threads-unread.json",
|
||||
"get-file-fragment?file-id=*&fragment-id=*":
|
||||
"viewer/get-file-fragment-single-board.json",
|
||||
"get-comments?thread-id=*": "workspace/get-thread-comments.json",
|
||||
"update-comment-thread-status":
|
||||
"workspace/update-comment-thread-status.json",
|
||||
});
|
||||
}
|
||||
|
||||
async clickWithDragViewportAt(x, y, width, height) {
|
||||
@@ -223,6 +351,67 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||
await this.page.mouse.up();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicks and moves from the coordinates x1,y1 to x2,y2
|
||||
*
|
||||
* @param {number} x1
|
||||
* @param {number} y1
|
||||
* @param {number} x2
|
||||
* @param {number} y2
|
||||
*/
|
||||
async clickAndMove(x1, y1, x2, y2) {
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.viewport.hover({ position: { x: x1, y: y1 } });
|
||||
await this.page.mouse.down();
|
||||
await this.viewport.hover({ position: { x: x2, y: y2 } });
|
||||
await this.page.mouse.up();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Text Shape in the specified coordinates
|
||||
* with an initial text.
|
||||
*
|
||||
* @param {number} x1
|
||||
* @param {number} y1
|
||||
* @param {number} x2
|
||||
* @param {number} y2
|
||||
* @param {string} initialText
|
||||
* @param {*} [options]
|
||||
*/
|
||||
async createTextShape(x1, y1, x2, y2, initialText, options) {
|
||||
const timeToWait = options?.timeToWait ?? 100;
|
||||
await this.page.keyboard.press("T");
|
||||
await this.page.waitForTimeout(timeToWait);
|
||||
await this.clickAndMove(x1, y1, x2, y2);
|
||||
await this.page.waitForTimeout(timeToWait);
|
||||
if (initialText) {
|
||||
await this.page.keyboard.type(initialText);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the selected element into the clipboard.
|
||||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async copy() {
|
||||
return this.page.keyboard.press("Control+C");
|
||||
}
|
||||
|
||||
/**
|
||||
* Pastes something from the clipboard.
|
||||
*
|
||||
* @param {"keyboard"|"context-menu"} [kind="keyboard"]
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async paste(kind = "keyboard") {
|
||||
if (kind === "context-menu") {
|
||||
await this.viewport.click({ button: "right" });
|
||||
return this.page.getByText("PasteCtrlV").click();
|
||||
}
|
||||
return this.page.keyboard.press("Control+V");
|
||||
}
|
||||
|
||||
async panOnViewportAt(x, y, width, height) {
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.viewport.hover({ position: { x, y } });
|
||||
@@ -250,10 +439,15 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||
await this.page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
async doubleClickLeafLayer(name, clickOptions = {}) {
|
||||
await this.clickLeafLayer(name, clickOptions);
|
||||
await this.clickLeafLayer(name, clickOptions);
|
||||
}
|
||||
|
||||
async clickToggableLayer(name, clickOptions = {}) {
|
||||
const layer = this.layers
|
||||
.getByTestId("layer-row")
|
||||
.filter({ hasText: name });
|
||||
.getByTestId("layer-row")
|
||||
.filter({ hasText: name });
|
||||
const button = layer.getByRole("button");
|
||||
|
||||
await button.waitFor();
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 23 KiB |
@@ -360,7 +360,7 @@ test("Renders a file with texts with paragraphs and breaking lines", async ({
|
||||
id: "a5f238bd-dd8a-8164-8007-1bc3481eaf05",
|
||||
pageId: "a5f238bd-dd8a-8164-8007-1bc3481eaf06",
|
||||
});
|
||||
await workspace.waitForFirstRender();
|
||||
await workspace.waitForFirstRenderWithoutUI();
|
||||
await expect(workspace.canvas).toHaveScreenshot();
|
||||
});
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ const setupFile = async (workspacePage) => {
|
||||
fileId: "7b2da435-6186-815a-8007-0daa95d2f26d",
|
||||
pageId: "ce79274b-11ab-8088-8007-0487ad43f789",
|
||||
});
|
||||
await workspacePage.mockRPC(
|
||||
"update-file?id=*",
|
||||
"workspace/update-file-empty.json",
|
||||
);
|
||||
};
|
||||
|
||||
const shapeToLayerName = {
|
||||
|
||||
@@ -1,12 +1,317 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
import { Clipboard } from '../../helpers/Clipboard';
|
||||
import { WorkspacePage } from "../pages/WorkspacePage";
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
const timeToWait = 100;
|
||||
|
||||
test.beforeEach(async ({ page, context }) => {
|
||||
await Clipboard.enable(context, Clipboard.Permission.ONLY_WRITE);
|
||||
|
||||
await WorkspacePage.init(page);
|
||||
await WorkspacePage.mockConfigFlags(page, ["enable-feature-text-editor-v2"]);
|
||||
});
|
||||
|
||||
test.skip("BUG 11552 - Apply styles to the current caret", async ({ page }) => {
|
||||
test.afterEach(async ({ context}) => {
|
||||
context.clearPermissions();
|
||||
})
|
||||
|
||||
test("Create a new text shape", async ({ page }) => {
|
||||
const initialText = "Lorem ipsum";
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.createTextShape(190, 150, 300, 200, initialText);
|
||||
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe(initialText);
|
||||
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("Create a new text shape from pasting text", async ({ page, context }) => {
|
||||
const textToPaste = "Lorem ipsum";
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true,
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockRPC(
|
||||
"update-file?id=*",
|
||||
"text-editor/update-file.json",
|
||||
);
|
||||
await workspace.goToWorkspace();
|
||||
|
||||
await Clipboard.writeText(page, textToPaste);
|
||||
|
||||
await workspace.clickAt(190, 150);
|
||||
await workspace.paste("keyboard");
|
||||
|
||||
await page.waitForTimeout(timeToWait);
|
||||
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe(textToPaste);
|
||||
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("Create a new text shape from pasting text using context menu", async ({ page, context }) => {
|
||||
const textToPaste = "Lorem ipsum";
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.goToWorkspace();
|
||||
|
||||
await Clipboard.writeText(page, textToPaste);
|
||||
|
||||
await workspace.clickAt(190, 150);
|
||||
await workspace.paste("context-menu");
|
||||
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe(textToPaste);
|
||||
|
||||
await workspace.textEditor.stopEditing();
|
||||
})
|
||||
|
||||
test("Update an already created text shape by appending text", async ({ page }) => {
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.moveFromEnd(0);
|
||||
await page.keyboard.type(" dolor sit amet");
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe("Lorem ipsum dolor sit amet");
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("Update an already created text shape by prepending text", async ({
|
||||
page,
|
||||
}) => {
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.moveFromStart(0);
|
||||
await page.keyboard.type("Dolor sit amet ");
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe("Dolor sit amet Lorem ipsum");
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("Update an already created text shape by inserting text in between", async ({
|
||||
page,
|
||||
}) => {
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.moveFromStart(5);
|
||||
await page.keyboard.type(" dolor sit amet");
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe("Lorem dolor sit amet ipsum");
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("Update a new text shape appending text by pasting text", async ({ page, context }) => {
|
||||
const textToPaste = " dolor sit amet";
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.goToWorkspace();
|
||||
|
||||
await Clipboard.writeText(page, textToPaste);
|
||||
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.moveFromEnd();
|
||||
await workspace.paste("keyboard");
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe("Lorem ipsum dolor sit amet");
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("Update a new text shape prepending text by pasting text", async ({
|
||||
page, context
|
||||
}) => {
|
||||
const textToPaste = "Dolor sit amet ";
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.goToWorkspace();
|
||||
|
||||
await Clipboard.writeText(page, textToPaste);
|
||||
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.moveFromStart();
|
||||
await workspace.paste("keyboard");
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe("Dolor sit amet Lorem ipsum");
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("Update a new text shape replacing (starting) text with pasted text", async ({
|
||||
page,
|
||||
}) => {
|
||||
const textToPaste = "Dolor sit amet";
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.selectFromStart(5);
|
||||
|
||||
await Clipboard.writeText(page, textToPaste);
|
||||
|
||||
await workspace.paste("keyboard");
|
||||
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe("Dolor sit amet ipsum");
|
||||
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("Update a new text shape replacing (ending) text with pasted text", async ({
|
||||
page,
|
||||
}) => {
|
||||
const textToPaste = "dolor sit amet";
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.selectFromEnd(5);
|
||||
|
||||
await Clipboard.writeText(page, textToPaste);
|
||||
|
||||
await workspace.paste("keyboard");
|
||||
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe("Lorem dolor sit amet");
|
||||
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("Update a new text shape replacing (in between) text with pasted text", async ({
|
||||
page,
|
||||
}) => {
|
||||
const textToPaste = "dolor sit amet";
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.selectFromStart(5, 3);
|
||||
|
||||
await Clipboard.writeText(page, textToPaste);
|
||||
|
||||
await workspace.paste("keyboard");
|
||||
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe("Lordolor sit ametsum");
|
||||
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("Update text font size selecting a part of it (starting)", async ({
|
||||
page,
|
||||
}) => {
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.mockRPC(
|
||||
"update-file?id=*",
|
||||
"text-editor/update-file.json",
|
||||
);
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.selectFromStart(5);
|
||||
await workspace.textEditor.changeFontSize(36);
|
||||
|
||||
const textContent1 = await workspace.textEditor.waitForTextSpanContent(1);
|
||||
expect(textContent1).toBe("Lorem");
|
||||
const textContent2 = await workspace.textEditor.waitForTextSpanContent(2);
|
||||
expect(textContent2).toBe(" ipsum");
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test.skip("Update text line height selecting a part of it (starting)", async ({
|
||||
page,
|
||||
}) => {
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true,
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.mockRPC("update-file?id=*", "text-editor/update-file.json");
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.selectFromStart(5);
|
||||
await workspace.textEditor.changeLineHeight(1.4);
|
||||
|
||||
const lineHeight = await workspace.textEditor.waitForParagraphStyle(1, 'line-height');
|
||||
expect(lineHeight).toBe("1.4");
|
||||
|
||||
const textContent = await workspace.textEditor.waitForTextSpanContent();
|
||||
expect(textContent).toBe("Lorem ipsum");
|
||||
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test.skip("Update text letter spacing selecting a part of it (starting)", async ({
|
||||
page,
|
||||
}) => {
|
||||
const workspace = new WorkspacePage(page, {
|
||||
textEditor: true,
|
||||
});
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-lorem-ipsum.json");
|
||||
await workspace.mockRPC("update-file?id=*", "text-editor/update-file.json");
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.textEditor.startEditing();
|
||||
await workspace.textEditor.selectFromStart(5);
|
||||
await workspace.textEditor.changeLetterSpacing(10);
|
||||
|
||||
const textContent1 = await workspace.textEditor.waitForTextSpanContent(1);
|
||||
expect(textContent1).toBe("Lorem");
|
||||
const textContent2 = await workspace.textEditor.waitForTextSpanContent(2);
|
||||
expect(textContent2).toBe(" ipsum");
|
||||
await workspace.textEditor.stopEditing();
|
||||
});
|
||||
|
||||
test("BUG 11552 - Apply styles to the current caret", async ({ page }) => {
|
||||
const workspace = new WorkspacePage(page);
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockGetFile("text-editor/get-file-11552.json");
|
||||
@@ -14,21 +319,16 @@ test.skip("BUG 11552 - Apply styles to the current caret", async ({ page }) => {
|
||||
"update-file?id=*",
|
||||
"text-editor/update-file-11552.json",
|
||||
);
|
||||
|
||||
await workspace.goToWorkspace({
|
||||
fileId: "238a17e0-75ff-8075-8006-934586ea2230",
|
||||
pageId: "238a17e0-75ff-8075-8006-934586ea2231",
|
||||
});
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.clickLeafLayer("Lorem ipsum");
|
||||
await workspace.goToWorkspace();
|
||||
await workspace.doubleClickLeafLayer("Lorem ipsum");
|
||||
|
||||
const fontSizeInput = workspace.rightSidebar.getByRole("textbox", {
|
||||
name: "Font Size",
|
||||
});
|
||||
await expect(fontSizeInput).toBeVisible();
|
||||
|
||||
await workspace.page.keyboard.press("Enter");
|
||||
await workspace.page.keyboard.press("ArrowRight");
|
||||
await page.keyboard.press("Enter");
|
||||
await page.keyboard.press("ArrowRight");
|
||||
|
||||
await fontSizeInput.fill("36");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user