added light mode tests
test fixes
|
@ -17,10 +17,7 @@ const mainTest = base.test.extend({
|
|||
});
|
||||
|
||||
const performanceTest = base.test.extend({
|
||||
workingFile: [
|
||||
'documents/Penpot - Design System v2.0.penpot',
|
||||
{ option: true },
|
||||
],
|
||||
workingFile: ['documents/Penpot - Design System v2.0.penpot', { option: true }],
|
||||
workingShapes: [
|
||||
{
|
||||
pageId: '582296a0-d6b1-11ec-a04a-cf2544e40df7',
|
||||
|
|
|
@ -11,5 +11,5 @@ export function radiansToDegrees(radians) {
|
|||
|
||||
export default {
|
||||
degreesToRadians,
|
||||
radiansToDegrees
|
||||
}
|
||||
radiansToDegrees,
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* @returns {DOMPoint}
|
||||
*/
|
||||
export function createPoint(x = 0, y = 0, z = 0, w = 1) {
|
||||
if (!("DOMPoint" in globalThis)) {
|
||||
if (!('DOMPoint' in globalThis)) {
|
||||
class DOMPoint {
|
||||
static fromPoint({ x = 0, y = 0, z = 0, w = 1 }) {
|
||||
return new DOMPoint(x, y, z, w);
|
||||
|
@ -37,7 +37,7 @@ export function createPoint(x = 0, y = 0, z = 0, w = 1) {
|
|||
* @returns {DOMRect}
|
||||
*/
|
||||
export function createRect(x = 0, y = 0, width = 0, height = 0) {
|
||||
if (!("DOMRect" in globalThis)) {
|
||||
if (!('DOMRect' in globalThis)) {
|
||||
class DOMRect {
|
||||
static fromRect({ x, y, width, height }) {
|
||||
return new DOMRect(x, y, width, height);
|
||||
|
|
|
@ -8,7 +8,7 @@ exports.BasePage = class BasePage {
|
|||
constructor(page) {
|
||||
this.page = page;
|
||||
this.header = page.locator('div[class*="dashboard-title"] h1');
|
||||
this.successMessage = page.locator('div[class="banner success fixed"]');
|
||||
this.successMessage = page.locator('div[class*="main_ui_messages__success"]');
|
||||
this.infoMessage = page.locator('div[class="banner info fixed"]');
|
||||
this.moveButton = page.locator('button[title="Move (V)"]');
|
||||
this.savedChangesIcon = page.locator('div[title="Saved"]');
|
||||
|
|
|
@ -45,6 +45,7 @@ exports.DashboardPage = class DashboardPage extends BasePage {
|
|||
this.downloadFileStandardMenuItem = page.locator(
|
||||
'a[data-test="download-standard-file"]',
|
||||
);
|
||||
this.dashboardSection = page.locator('[class="main_ui_dashboard__dashboard"]');
|
||||
this.downloadFileTickIcon = page.locator('svg[class="icon-tick-refactor"]');
|
||||
this.downloadFileCloseButton = page.locator('input[value="Close"]');
|
||||
this.fileNameInput = page.locator('div[class*="edit-wrapper"]');
|
||||
|
@ -117,7 +118,7 @@ exports.DashboardPage = class DashboardPage extends BasePage {
|
|||
this.fontNameInput = page.locator('div[class*="table-row"] input[type="text"]');
|
||||
this.saveFontButton = page.locator('button:text-is("Save")');
|
||||
this.searchFontInput = page.locator('input[placeholder="Search font"]');
|
||||
this.fontFormatError = page.locator('div[class="banner error fixed"]');
|
||||
this.fontFormatError = page.locator('.main_ui_messages__content span');
|
||||
|
||||
//Libraries & Templates
|
||||
this.noLibrariesPlacelder = page.locator('div[data-test="empty-placeholder"] p');
|
||||
|
|
|
@ -86,6 +86,8 @@ exports.TeamPage = class TeamPage extends BasePage {
|
|||
this.invitationWarningSpan = page.locator(
|
||||
'div[class*="warning-msg"] span[class*="team__message"]',
|
||||
);
|
||||
this.teamSettingsSection = page.locator('.main_ui_dashboard__dashboard-content');
|
||||
this.teamIcon = page.locator(`div[class*='team__icon'] span`);
|
||||
}
|
||||
|
||||
async createTeam(teamName) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { expect } from "@playwright/test";
|
||||
import { BasePage } from "./base-page";
|
||||
import { createPoint, createRect, getCenterPoint } from "../helpers/rect";
|
||||
import { degreesToRadians } from "../helpers/angle";
|
||||
import { expect } from '@playwright/test';
|
||||
import { BasePage } from './base-page';
|
||||
import { createPoint, createRect, getCenterPoint } from '../helpers/rect';
|
||||
import { degreesToRadians } from '../helpers/angle';
|
||||
|
||||
exports.PerformancePage = class PerformancePage extends BasePage {
|
||||
/**
|
||||
|
@ -12,8 +12,8 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
constructor(page) {
|
||||
super(page);
|
||||
|
||||
this.viewportControls = page.locator(".viewport-controls");
|
||||
this.selectionHandlers = page.locator(".selection-handlers");
|
||||
this.viewportControls = page.locator('.viewport-controls');
|
||||
this.selectionHandlers = page.locator('.selection-handlers');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,7 +22,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
* @returns {Promise<void>}
|
||||
*/
|
||||
async waitForPageLoaded() {
|
||||
await this.page.waitForLoadState("networkidle");
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,7 +40,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
* @returns {Promise<void>}
|
||||
*/
|
||||
async waitForSelectionHandlers() {
|
||||
await this.page.waitForSelector(".selection-handlers", { delay: 100 });
|
||||
await this.page.waitForSelector('.selection-handlers', { delay: 100 });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,7 +54,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
console.log(list.getEntries());
|
||||
});
|
||||
window.penpotPerformanceObserver.observe({
|
||||
entryTypes: ["longtask", "taskattribution"],
|
||||
entryTypes: ['longtask', 'taskattribution'],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -174,16 +174,14 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
this.#framesPerSecond = this.#frameCount;
|
||||
this.#frameCount = 0;
|
||||
|
||||
const shouldContinue = this.#recorder.record(
|
||||
this.#framesPerSecond,
|
||||
);
|
||||
const shouldContinue = this.#recorder.record(this.#framesPerSecond);
|
||||
if (!shouldContinue && this.#shouldStopWhenFull) {
|
||||
shouldStop = true;
|
||||
}
|
||||
}
|
||||
if (shouldStop) {
|
||||
if (this.stop()) {
|
||||
this.dispatchEvent(new Event("ended"));
|
||||
this.dispatchEvent(new Event('ended'));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -218,7 +216,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
}
|
||||
|
||||
// If the FrameRateRecorder is already defined, do nothing.
|
||||
if (typeof window.FrameRateRecorder !== "function") {
|
||||
if (typeof window.FrameRateRecorder !== 'function') {
|
||||
window.FrameRateRecorder = provide();
|
||||
}
|
||||
});
|
||||
|
@ -229,27 +227,24 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
*
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
startRecordingFrameRate({
|
||||
maxRecords = 60 * 60,
|
||||
shouldStopWhenFull = true,
|
||||
} = {}) {
|
||||
startRecordingFrameRate({ maxRecords = 60 * 60, shouldStopWhenFull = true } = {}) {
|
||||
return this.page.evaluate(
|
||||
({ maxRecords, shouldStopWhenFull }) => {
|
||||
if (typeof window.FrameRateRecorder !== "function") {
|
||||
if (typeof window.FrameRateRecorder !== 'function') {
|
||||
throw new Error(
|
||||
"FrameRateRecorder is not defined. Call `injectFrameRateRecorder` first.",
|
||||
'FrameRateRecorder is not defined. Call `injectFrameRateRecorder` first.',
|
||||
);
|
||||
}
|
||||
|
||||
window.penpotFrameRateRecorder_OnEnded = () => {
|
||||
throw new Error("Insufficient buffer size to record frame rate.");
|
||||
throw new Error('Insufficient buffer size to record frame rate.');
|
||||
};
|
||||
window.penpotFrameRateRecorder = new FrameRateRecorder({
|
||||
maxRecords,
|
||||
shouldStopWhenFull,
|
||||
});
|
||||
window.penpotFrameRateRecorder.addEventListener(
|
||||
"ended",
|
||||
'ended',
|
||||
window.penpotFrameRateRecorder_OnEnded,
|
||||
);
|
||||
window.penpotFrameRateRecorder.start();
|
||||
|
@ -265,13 +260,13 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
*/
|
||||
stopRecordingFrameRate() {
|
||||
return this.page.evaluate(() => {
|
||||
if (typeof window.FrameRateRecorder !== "function") {
|
||||
if (typeof window.FrameRateRecorder !== 'function') {
|
||||
throw new Error(
|
||||
"FrameRateRecorder is not defined. Call `injectFrameRateRecorder` first.",
|
||||
'FrameRateRecorder is not defined. Call `injectFrameRateRecorder` first.',
|
||||
);
|
||||
}
|
||||
window.penpotFrameRateRecorder.removeEventListener(
|
||||
"ended",
|
||||
'ended',
|
||||
window.penpotFrameRateRecorder_OnEnded,
|
||||
);
|
||||
window.penpotFrameRateRecorder.stop();
|
||||
|
@ -357,7 +352,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
* @returns {Promise<Locator>}
|
||||
*/
|
||||
async getSelectorOrLocator(selectorOrLocator) {
|
||||
if (typeof selectorOrLocator === "string") {
|
||||
if (typeof selectorOrLocator === 'string') {
|
||||
return this.page.locator(selectorOrLocator);
|
||||
}
|
||||
return selectorOrLocator;
|
||||
|
@ -388,35 +383,38 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
);
|
||||
|
||||
const boundingClientRect = await Promise.all(
|
||||
boundingBoxes.reduce((rect, boundingBox) => {
|
||||
const { top, left, bottom, right } = boundingBox;
|
||||
rect.top = Math.min(top, rect.top);
|
||||
rect.left = Math.min(left, rect.left);
|
||||
rect.bottom = Math.max(bottom, rect.bottom);
|
||||
rect.right = Math.max(right, rect.right);
|
||||
return rect;
|
||||
}, createRect(Infinity, Infinity, -Infinity, -Infinity)),
|
||||
boundingBoxes.reduce(
|
||||
(rect, boundingBox) => {
|
||||
const { top, left, bottom, right } = boundingBox;
|
||||
rect.top = Math.min(top, rect.top);
|
||||
rect.left = Math.min(left, rect.left);
|
||||
rect.bottom = Math.max(bottom, rect.bottom);
|
||||
rect.right = Math.max(right, rect.right);
|
||||
return rect;
|
||||
},
|
||||
createRect(Infinity, Infinity, -Infinity, -Infinity),
|
||||
),
|
||||
);
|
||||
|
||||
return boundingClientRect
|
||||
return boundingClientRect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Undo the last action.
|
||||
*/
|
||||
async undo() {
|
||||
await this.page.keyboard.down("Control");
|
||||
await this.page.keyboard.press("KeyZ");
|
||||
await this.page.keyboard.up("Control");
|
||||
await this.page.keyboard.down('Control');
|
||||
await this.page.keyboard.press('KeyZ');
|
||||
await this.page.keyboard.up('Control');
|
||||
}
|
||||
|
||||
/**
|
||||
* Redoes the last action.
|
||||
*/
|
||||
async redo() {
|
||||
await this.page.keyboard.down("Control");
|
||||
await this.page.keyboard.press("KeyY");
|
||||
await this.page.keyboard.up("Control");
|
||||
await this.page.keyboard.down('Control');
|
||||
await this.page.keyboard.press('KeyY');
|
||||
await this.page.keyboard.up('Control');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -437,11 +435,11 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
async measure() {
|
||||
const [frameRateRecords, longTasksRecords] = await this.stopAll();
|
||||
const averageFrameRate = this.calculateAverageFrameRate(frameRateRecords);
|
||||
console.log("FPS", averageFrameRate);
|
||||
console.log('FPS', averageFrameRate);
|
||||
expect(averageFrameRate).toBeGreaterThan(30);
|
||||
const averageLongTaskDuration =
|
||||
this.calculateAverageLongTaskDuration(longTasksRecords);
|
||||
console.log("LTS", averageLongTaskDuration);
|
||||
console.log('LTS', averageLongTaskDuration);
|
||||
expect(averageLongTaskDuration).toBeLessThan(100);
|
||||
return [averageFrameRate, averageLongTaskDuration];
|
||||
}
|
||||
|
@ -456,9 +454,9 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
*/
|
||||
async pan(dx, dy, steps) {
|
||||
await this.waitForViewportControls();
|
||||
await this.page.mouse.down({ button: "middle" });
|
||||
await this.page.mouse.down({ button: 'middle' });
|
||||
await this.page.mouse.move(dx, dy, { steps });
|
||||
await this.page.mouse.up({ button: "middle" });
|
||||
await this.page.mouse.up({ button: 'middle' });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -474,9 +472,9 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
async panFromTo(fx, fy, tx, ty, steps) {
|
||||
await this.waitForViewportControls();
|
||||
await this.page.mouse.move(tx, ty);
|
||||
await this.page.mouse.down({ button: "middle" });
|
||||
await this.page.mouse.down({ button: 'middle' });
|
||||
await this.page.mouse.move(fx, fy, { steps });
|
||||
await this.page.mouse.up({ button: "middle" });
|
||||
await this.page.mouse.up({ button: 'middle' });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -488,11 +486,11 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
*/
|
||||
async zoom(dy, steps) {
|
||||
await this.waitForViewportControls();
|
||||
await this.page.keyboard.down("Control");
|
||||
await this.page.keyboard.down('Control');
|
||||
for (let index = 0; index < steps; index++) {
|
||||
await this.page.mouse.wheel(0, dy);
|
||||
}
|
||||
await this.page.keyboard.up("Control");
|
||||
await this.page.keyboard.up('Control');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -503,9 +501,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
*/
|
||||
async centerInView(selectorOrLocator) {
|
||||
await this.waitForViewportControls();
|
||||
const viewportRect = await this.getBoundingClientRect(
|
||||
this.viewportControls,
|
||||
);
|
||||
const viewportRect = await this.getBoundingClientRect(this.viewportControls);
|
||||
const centerPoint = getCenterPoint(viewportRect);
|
||||
const element = await this.getSelectorOrLocator(selectorOrLocator);
|
||||
const elementRect = await this.getBoundingClientRect(element);
|
||||
|
@ -521,9 +517,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
}
|
||||
|
||||
async centerSelectedInView() {
|
||||
const viewportRect = await this.getBoundingClientRect(
|
||||
this.viewportControls,
|
||||
);
|
||||
const viewportRect = await this.getBoundingClientRect(this.viewportControls);
|
||||
const centerPoint = getCenterPoint(viewportRect);
|
||||
const elementRect = await this.getBoundingClientRect(this.selectionHandlers);
|
||||
const elementCenterPoint = getCenterPoint(elementRect);
|
||||
|
@ -576,7 +570,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
* @returns {Promise<void>}
|
||||
*/
|
||||
async selectShapes(shapeIds) {
|
||||
await this.page.keyboard.down("Shift");
|
||||
await this.page.keyboard.down('Shift');
|
||||
for (const shapeId of shapeIds) {
|
||||
const locator = await this.page.locator(shapeId);
|
||||
const { x, y, width, height } = await locator.boundingBox();
|
||||
|
@ -584,7 +578,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
await this.page.mouse.click(x + width / 2, y + height / 2);
|
||||
await this.page.waitForTimeout(100);
|
||||
}
|
||||
await this.page.keyboard.up("Shift");
|
||||
await this.page.keyboard.up('Shift');
|
||||
await this.page.waitForTimeout(100);
|
||||
}
|
||||
|
||||
|
@ -601,14 +595,17 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
if (shapes.some((shape) => !shape)) {
|
||||
throw new Error(`Shape "shape-${shapeId}" not found.`);
|
||||
}
|
||||
const boundingClientRect = shapes.reduce((rect, shape) => {
|
||||
const { top, left, bottom, right } = shape.getBoundingClientRect();
|
||||
rect.top = Math.min(top, rect.top);
|
||||
rect.left = Math.min(left, rect.left);
|
||||
rect.bottom = Math.max(bottom, rect.bottom);
|
||||
rect.right = Math.max(right, rect.right);
|
||||
return rect;
|
||||
}, new DOMRect(Infinity, Infinity, -Infinity, -Infinity));
|
||||
const boundingClientRect = shapes.reduce(
|
||||
(rect, shape) => {
|
||||
const { top, left, bottom, right } = shape.getBoundingClientRect();
|
||||
rect.top = Math.min(top, rect.top);
|
||||
rect.left = Math.min(left, rect.left);
|
||||
rect.bottom = Math.max(bottom, rect.bottom);
|
||||
rect.right = Math.max(right, rect.right);
|
||||
return rect;
|
||||
},
|
||||
new DOMRect(Infinity, Infinity, -Infinity, -Infinity),
|
||||
);
|
||||
return boundingClientRect;
|
||||
}, shapeIds);
|
||||
}
|
||||
|
@ -619,21 +616,21 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
* @param {string} name
|
||||
* @returns {Promise<ElementHandle>}
|
||||
*/
|
||||
async getResizeHandler(name = "bottom-right") {
|
||||
async getResizeHandler(name = 'bottom-right') {
|
||||
const names = [
|
||||
"top",
|
||||
"bottom",
|
||||
"right",
|
||||
"left",
|
||||
"top-left",
|
||||
"top-right",
|
||||
"bottom-right",
|
||||
"bottom-left",
|
||||
'top',
|
||||
'bottom',
|
||||
'right',
|
||||
'left',
|
||||
'top-left',
|
||||
'top-right',
|
||||
'bottom-right',
|
||||
'bottom-left',
|
||||
];
|
||||
|
||||
// -}~:Ztva;:E]gU8u$[Vf
|
||||
|
||||
const handlers = await this.page.$$("g.resize-handler");
|
||||
const handlers = await this.page.$$('g.resize-handler');
|
||||
if (handlers.length < names.length) {
|
||||
throw new Error(`Invalid amount of resize handlers.`);
|
||||
}
|
||||
|
@ -651,12 +648,12 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
* @param {string} position
|
||||
* @returns {Promise<ElementHandle>}
|
||||
*/
|
||||
async getRotateHandler(position = "top-left") {
|
||||
async getRotateHandler(position = 'top-left') {
|
||||
const positions = new Map([
|
||||
["top-left", "0"],
|
||||
["top-right", "90"],
|
||||
["bottom-right", "180"],
|
||||
["bottom-left", "270"],
|
||||
['top-left', '0'],
|
||||
['top-right', '90'],
|
||||
['bottom-right', '180'],
|
||||
['bottom-left', '270'],
|
||||
]);
|
||||
return this.page.$(`rect.cursor-rotate-${positions.get(position)}`);
|
||||
}
|
||||
|
@ -676,17 +673,15 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
y,
|
||||
{ x: dx = 2, y: dy = 2, steps = 10 } = {},
|
||||
) {
|
||||
const { x: ex, y: ey } = await this.getBoundingClientRect(
|
||||
selectorOrLocator,
|
||||
);
|
||||
const { x: ex, y: ey } = await this.getBoundingClientRect(selectorOrLocator);
|
||||
await this.page.mouse.click(ex + dx, ey + dy);
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.click(ex + dx, ey + dy);
|
||||
await this.page.mouse.down({ button: "left" });
|
||||
await this.page.mouse.down({ button: 'left' });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.move(ex + x, ey + y, { steps });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.up({ button: "left" });
|
||||
await this.page.mouse.up({ button: 'left' });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -699,13 +694,18 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
*/
|
||||
async moveSelectedBy(x, y, { x: dx = 2, y: dy = 2, steps = 10 } = {}) {
|
||||
await this.waitForSelectionHandlers();
|
||||
const { x: ex, y: ey, width, height } = await this.getBoundingClientRect(this.selectionHandlers);
|
||||
console.log(x, y, width, height)
|
||||
await this.page.mouse.down({ button: "left" });
|
||||
const {
|
||||
x: ex,
|
||||
y: ey,
|
||||
width,
|
||||
height,
|
||||
} = await this.getBoundingClientRect(this.selectionHandlers);
|
||||
console.log(x, y, width, height);
|
||||
await this.page.mouse.down({ button: 'left' });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.move(ex + x, ey + y, { steps });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.up({ button: "left" });
|
||||
await this.page.mouse.up({ button: 'left' });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -719,7 +719,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
async rotateShapeBy(selectorOrLocator, degrees, { steps = 10 } = {}) {
|
||||
const boundingBox = await this.getBoundingClientRect(selectorOrLocator);
|
||||
const { x: centerX, y: centerY } = getCenterPoint(boundingBox);
|
||||
const rotateHandler = await this.getRotateHandler("top-left");
|
||||
const rotateHandler = await this.getRotateHandler('top-left');
|
||||
const { x: rx, y: ry } = await this.getBoundingClientRect(rotateHandler);
|
||||
const radians = degreesToRadians(degrees);
|
||||
const dx = Math.cos(radians);
|
||||
|
@ -729,11 +729,11 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
const y = centerY + dy * d;
|
||||
await rotateHandler.click();
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.down({ button: "left" });
|
||||
await this.page.mouse.down({ button: 'left' });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.move(x, y, { steps });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.up({ button: "left" });
|
||||
await this.page.mouse.up({ button: 'left' });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -749,7 +749,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
this.selectionHandlers,
|
||||
);
|
||||
const { x: centerX, y: centerY } = getCenterPoint(boundingBox);
|
||||
const rotateHandler = await this.getRotateHandler("top-left");
|
||||
const rotateHandler = await this.getRotateHandler('top-left');
|
||||
const { x: rx, y: ry } = await this.getBoundingClientRect(rotateHandler);
|
||||
const radians = degreesToRadians(degrees);
|
||||
const dx = Math.cos(radians);
|
||||
|
@ -759,11 +759,11 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
const y = centerY + dy * d;
|
||||
await rotateHandler.click();
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.down({ button: "left" });
|
||||
await this.page.mouse.down({ button: 'left' });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.move(x, y, { steps });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.up({ button: "left" });
|
||||
await this.page.mouse.up({ button: 'left' });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -778,7 +778,7 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
selectorOrLocator,
|
||||
sx,
|
||||
sy,
|
||||
{ x: dx = 2, y: dy = 2, steps = 10, handler = "bottom-right" } = {},
|
||||
{ x: dx = 2, y: dy = 2, steps = 10, handler = 'bottom-right' } = {},
|
||||
) {
|
||||
// Clicks on the element to select it.
|
||||
const { x: ex, y: ey } = await this.getBoundingClientRect(selectorOrLocator);
|
||||
|
@ -790,11 +790,11 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
console.log(x, y, x + sx, y + sy);
|
||||
await resizeHandler.click();
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.down({ button: "left" });
|
||||
await this.page.mouse.down({ button: 'left' });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.move(x + sx, y + sy, { steps });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.up({ button: "left" });
|
||||
await this.page.mouse.up({ button: 'left' });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -805,17 +805,21 @@ exports.PerformancePage = class PerformancePage extends BasePage {
|
|||
* @param {object} [options]
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async scaleSelectedBy(sx, sy, { x: dx = 2, y: dy = 2, steps = 10, handler = "bottom-right" } = {}) {
|
||||
async scaleSelectedBy(
|
||||
sx,
|
||||
sy,
|
||||
{ x: dx = 2, y: dy = 2, steps = 10, handler = 'bottom-right' } = {},
|
||||
) {
|
||||
// Clicks on the element to select it.
|
||||
await this.waitForSelectionHandlers();
|
||||
const resizeHandler = await this.getResizeHandler(handler);
|
||||
const { x, y } = await this.getBoundingClientRect(resizeHandler);
|
||||
await resizeHandler.click();
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.down({ button: "left" });
|
||||
await this.page.mouse.down({ button: 'left' });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.move(x + sx, y + sy, { steps });
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.page.mouse.up({ button: "left" });
|
||||
await this.page.mouse.up({ button: 'left' });
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,6 +8,8 @@ exports.ProfilePage = class ProfilePage extends BasePage {
|
|||
constructor(page) {
|
||||
super(page);
|
||||
|
||||
this.profileSection = page.locator('.main_ui_settings__dashboard-content');
|
||||
|
||||
//Account
|
||||
this.profileMenuButton = page.locator('div[data-test="profile-btn"]');
|
||||
this.yourAccountMenuItem = page.locator('li[data-test="profile-profile-opt"]');
|
||||
|
@ -37,8 +39,15 @@ exports.ProfilePage = class ProfilePage extends BasePage {
|
|||
this.passwordOldInput = page.locator('#password-old');
|
||||
this.passwordNewInput = page.locator('input[label="New password"]');
|
||||
this.passwordConfirmInput = page.locator('input[label="Confirm password"]');
|
||||
this.updateSettingsBtn = page.locator('button[data-test="submit-password"]');
|
||||
this.updateSettingsBtn = page.locator('button[name="submit"]');
|
||||
this.passwordInputError = page.locator('div[data-test="-error"]');
|
||||
|
||||
//Settings
|
||||
this.settingsMenuButton = page.locator('li[data-test="settings-profile"]');
|
||||
this.darkThemeOption = page.locator('li span:text-is("Penpot Dark (default)")');
|
||||
this.lightThemeOption = page.locator('li span:text-is("Penpot Light")');
|
||||
this.uiThemeDropdown = page.locator('[class*="select-wrapper"] >>nth=1');
|
||||
this.giveFeedbackMenuItem = page.locator('li[data-test="feedback-profile-opt"]');
|
||||
}
|
||||
|
||||
async openYourAccountPage() {
|
||||
|
@ -46,11 +55,19 @@ exports.ProfilePage = class ProfilePage extends BasePage {
|
|||
await this.yourAccountMenuItem.click();
|
||||
}
|
||||
|
||||
async goToAccountPage() {
|
||||
await this.page.goto('https://design.penpot.dev/#/settings/profile');
|
||||
}
|
||||
|
||||
async openGiveFeedbackPage() {
|
||||
await this.profileMenuButton.click();
|
||||
await this.giveFeedbackMenuItem.click();
|
||||
}
|
||||
|
||||
async clickOnProfileTab() {
|
||||
await this.profileMenuButton.click();
|
||||
}
|
||||
|
||||
async openPasswordPageInAccount() {
|
||||
await this.passwordSidebarOption.click();
|
||||
await expect(this.passwordFormHeader).toHaveText('Change password');
|
||||
|
@ -119,4 +136,22 @@ exports.ProfilePage = class ProfilePage extends BasePage {
|
|||
await this.backToDashboardBtn.click();
|
||||
await this.isHeaderDisplayed('Projects');
|
||||
}
|
||||
|
||||
async selectLightTheme() {
|
||||
await this.uiThemeDropdown.click();
|
||||
await this.lightThemeOption.click();
|
||||
await this.updateSettingsBtn.click();
|
||||
await this.isSuccessMessageDisplayed('Profile saved successfully!');
|
||||
}
|
||||
|
||||
async selectDarkTheme() {
|
||||
await this.uiThemeDropdown.click();
|
||||
await this.darkThemeOption.click();
|
||||
await this.updateSettingsBtn.click();
|
||||
await this.isSuccessMessageDisplayed('Profile saved successfully!');
|
||||
}
|
||||
|
||||
async openSettingsTab() {
|
||||
await this.settingsMenuButton.click();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -184,6 +184,9 @@ exports.MainPage = class MainPage extends BasePage {
|
|||
this.closeShortcutsPanelIcon = page.locator(
|
||||
'div[class*="shortcuts-close-button"]',
|
||||
);
|
||||
|
||||
this.fileLeftSidebarAside = page.locator('#left-sidebar-aside');
|
||||
this.fileRightSidebarAside = page.locator('#right-sidebar-aside');
|
||||
}
|
||||
|
||||
async clickCreateBoardButton() {
|
||||
|
@ -239,20 +242,20 @@ exports.MainPage = class MainPage extends BasePage {
|
|||
}
|
||||
|
||||
async clickViewportTwice() {
|
||||
await this.page.waitForTimeout(100)
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.viewport.hover();
|
||||
await this.viewport.click({ delay: 100, force: true });
|
||||
await this.page.waitForTimeout(100)
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.viewport.click({ delay: 100, force: true });
|
||||
}
|
||||
|
||||
async clickViewportByCoordinates(x, y, count = 1) {
|
||||
await this.page.waitForTimeout(100)
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.viewport.hover();
|
||||
for (let i = 0; i < count; i++) {
|
||||
await this.page.waitForTimeout(100)
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.viewport.click({
|
||||
position: {x: x, y: y},
|
||||
position: { x: x, y: y },
|
||||
force: true,
|
||||
delay: 200,
|
||||
});
|
||||
|
@ -291,7 +294,7 @@ exports.MainPage = class MainPage extends BasePage {
|
|||
}
|
||||
|
||||
async drawCurve(x1, y1, x2, y2) {
|
||||
await this.page.waitForTimeout(100)
|
||||
await this.page.waitForTimeout(100);
|
||||
await this.viewport.hover();
|
||||
await this.page.mouse.move(x1, y1);
|
||||
await this.page.mouse.down();
|
||||
|
@ -730,22 +733,25 @@ exports.MainPage = class MainPage extends BasePage {
|
|||
async createDefaultBoardByCoordinates(x, y, double = false) {
|
||||
await this.clickCreateBoardButton();
|
||||
await this.clickViewportByCoordinates(x, y);
|
||||
double === true ? await this.clickViewportByCoordinates(x, y) :
|
||||
await this.waitForChangeIsSaved();
|
||||
double === true
|
||||
? await this.clickViewportByCoordinates(x, y)
|
||||
: await this.waitForChangeIsSaved();
|
||||
}
|
||||
|
||||
async createDefaultRectangleByCoordinates(x, y, double = false) {
|
||||
await this.clickCreateRectangleButton();
|
||||
await this.clickViewportByCoordinates(x, y);
|
||||
double === true ? await this.clickViewportByCoordinates(x, y) :
|
||||
await this.waitForChangeIsSaved();
|
||||
double === true
|
||||
? await this.clickViewportByCoordinates(x, y)
|
||||
: await this.waitForChangeIsSaved();
|
||||
}
|
||||
|
||||
async createDefaultEllipseByCoordinates(x, y, double = false) {
|
||||
await this.clickCreateEllipseButton();
|
||||
await this.clickViewportByCoordinates(x, y);
|
||||
double === true ? await this.clickViewportByCoordinates(x, y) :
|
||||
await this.waitForChangeIsSaved();
|
||||
double === true
|
||||
? await this.clickViewportByCoordinates(x, y)
|
||||
: await this.waitForChangeIsSaved();
|
||||
}
|
||||
|
||||
async createDefaultClosedPath() {
|
||||
|
|
4
pages/workspace/prototype-panel-page.js
vendored
|
@ -36,9 +36,9 @@ exports.PrototypePanelPage = class PrototypePanelPage extends BasePage {
|
|||
}
|
||||
|
||||
async dragAndDropPrototypeArrowConnector(x, y) {
|
||||
await this.page.waitForTimeout(200)
|
||||
await this.page.waitForTimeout(200);
|
||||
await this.prototypeArrowConnector.hover();
|
||||
await this.viewport.click()
|
||||
await this.viewport.click();
|
||||
await this.prototypeArrowConnector.dragTo(this.viewport, {
|
||||
force: false,
|
||||
targetPosition: { x: x, y: y },
|
||||
|
|
31
pages/workspace/view-mode-page.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
const { BasePage } = require('../base-page');
|
||||
const { expect } = require('@playwright/test');
|
||||
|
||||
exports.ViewModePage = class ViewModePage extends BasePage {
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
constructor(page) {
|
||||
super(page);
|
||||
|
||||
//Assets panel
|
||||
this.viewModeButton = page.locator(`a[class*='viewer-btn']`);
|
||||
this.viewerLoyautSection = page.locator('#viewer-layout');
|
||||
this.inspectButton = page.locator(`button .icon-code-refactor`);
|
||||
this.rightSidebar = page.locator(`aside[class*='inspect_right_sidebar']`);
|
||||
}
|
||||
|
||||
async clickViewModeButton() {
|
||||
await this.viewModeButton.click();
|
||||
const [newPage] = await Promise.all([
|
||||
this.page.context().waitForEvent('page'),
|
||||
this.page.waitForTimeout(300),
|
||||
]);
|
||||
return newPage;
|
||||
}
|
||||
|
||||
async openInspectTab() {
|
||||
await this.inspectButton.click();
|
||||
await expect(this.rightSidebar).toBeVisible();
|
||||
}
|
||||
};
|
|
@ -209,38 +209,38 @@ test.describe(() => {
|
|||
await mainPage.waitForChangeIsSaved();
|
||||
await expect(mainPage.viewport).toHaveScreenshot(
|
||||
'path-drop-shadow-default.png',
|
||||
{
|
||||
mask: [mainPage.guides],
|
||||
},
|
||||
// {
|
||||
// mask: [mainPage.guides],
|
||||
// },
|
||||
);
|
||||
await designPanelPage.hideShadow();
|
||||
await mainPage.waitForChangeIsSaved();
|
||||
await expect(mainPage.viewport).toHaveScreenshot('path-drop-shadow-hide.png', {
|
||||
mask: [mainPage.guides],
|
||||
// mask: [mainPage.guides],
|
||||
});
|
||||
await designPanelPage.unhideShadow();
|
||||
await mainPage.waitForChangeIsSaved();
|
||||
await expect(mainPage.viewport).toHaveScreenshot(
|
||||
'path-drop-shadow-unhide.png',
|
||||
{
|
||||
mask: [mainPage.guides],
|
||||
},
|
||||
// {
|
||||
// mask: [mainPage.guides],
|
||||
// },
|
||||
);
|
||||
await designPanelPage.selectTypeForShadow('Inner shadow');
|
||||
await mainPage.waitForChangeIsSaved();
|
||||
await expect(mainPage.viewport).toHaveScreenshot(
|
||||
'path-inner-shadow-default.png',
|
||||
{
|
||||
mask: [mainPage.guides],
|
||||
},
|
||||
// {
|
||||
// mask: [mainPage.guides],
|
||||
// },
|
||||
);
|
||||
await designPanelPage.removeShadow();
|
||||
await mainPage.waitForChangeIsSaved();
|
||||
await expect(mainPage.viewport).toHaveScreenshot(
|
||||
'path-inner-shadow-remove.png',
|
||||
{
|
||||
mask: [mainPage.guides],
|
||||
},
|
||||
// {
|
||||
// mask: [mainPage.guides],
|
||||
// },
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 73 KiB |
|
@ -1,5 +1,5 @@
|
|||
import { expect, test } from '@playwright/test'
|
||||
import { PerformancePage } from '../../pages/performance-page'
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { PerformancePage } from '../../pages/performance-page';
|
||||
|
||||
function waitForSeconds(timeInSeconds) {
|
||||
return new Promise((resolve) => setTimeout(() => resolve(), timeInSeconds * 1000));
|
||||
|
@ -13,10 +13,11 @@ test('PERF Measure frames per second', async ({ page }) => {
|
|||
const records = await performancePage.stopRecordingFrameRate();
|
||||
// This is an example of how to use the performance page
|
||||
// API, in idle time we should have average ~60 frames per second.
|
||||
const averageFrameRate = records.reduce((acc, record) => acc + record.value, 0) / records.length;
|
||||
const averageFrameRate =
|
||||
records.reduce((acc, record) => acc + record.value, 0) / records.length;
|
||||
expect(averageFrameRate).toBeGreaterThan(55);
|
||||
expect(averageFrameRate).toBeLessThan(65);
|
||||
})
|
||||
});
|
||||
|
||||
test('PERF Measure lockings (frames per second ~= 0)', async ({ page }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
|
@ -33,7 +34,7 @@ test('PERF Measure lockings (frames per second ~= 0)', async ({ page }) => {
|
|||
// If frame rate is less than 5 frames per second we can assume
|
||||
// that the main thread was locked.
|
||||
records.some((record) => expect(record.value).toBeLessThan(5));
|
||||
})
|
||||
});
|
||||
|
||||
test('PERF Measure long tasks', async ({ page }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
const { test } = require("@playwright/test");
|
||||
const { test } = require('@playwright/test');
|
||||
|
||||
test('PERF Render shapes with blur', async ({ page }) => {
|
||||
test('PERF Render shapes with blur', async ({ page }) => {});
|
||||
|
||||
})
|
||||
|
||||
test('PERF Render shapes with drop-shadow', async ({ page }) => {
|
||||
|
||||
})
|
||||
test('PERF Render shapes with drop-shadow', async ({ page }) => {});
|
||||
|
|
|
@ -1,150 +1,181 @@
|
|||
import { expect } from "@playwright/test";
|
||||
import { performanceTest } from "../../fixtures.js";
|
||||
import { PerformancePage } from "../../pages/performance-page";
|
||||
import { expect } from '@playwright/test';
|
||||
import { performanceTest } from '../../fixtures.js';
|
||||
import { PerformancePage } from '../../pages/performance-page';
|
||||
|
||||
performanceTest("PERF Shape (single): Move single shape", async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
performanceTest(
|
||||
'PERF Shape (single): Move single shape',
|
||||
async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
// IMPORTANT: We need to set the click position because we can have
|
||||
// shapes overlapping each other and we need to make sure we click
|
||||
// the right one.
|
||||
await performancePage.selectShape(workingShapes.singleId, { x: 5, y: 10 });
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.moveShapeBy(workingShapes.singleId, -100, -100, { x: 5, y: 10, steps: 100 });
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
// IMPORTANT: We need to set the click position because we can have
|
||||
// shapes overlapping each other and we need to make sure we click
|
||||
// the right one.
|
||||
await performancePage.selectShape(workingShapes.singleId, { x: 5, y: 10 });
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.moveShapeBy(workingShapes.singleId, -100, -100, {
|
||||
x: 5,
|
||||
y: 10,
|
||||
steps: 100,
|
||||
});
|
||||
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
});
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
},
|
||||
);
|
||||
|
||||
performanceTest("PERF Shape (single): Rotate single shape", async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
performanceTest(
|
||||
'PERF Shape (single): Rotate single shape',
|
||||
async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
// IMPORTANT: We need to set the click position because we can have
|
||||
// shapes overlapping each other and we need to make sure we click
|
||||
// the right one.
|
||||
await performancePage.selectShape(workingShapes.singleId, { x: 5, y: 10 });
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.rotateShapeBy(workingShapes.singleId, 45);
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
// IMPORTANT: We need to set the click position because we can have
|
||||
// shapes overlapping each other and we need to make sure we click
|
||||
// the right one.
|
||||
await performancePage.selectShape(workingShapes.singleId, { x: 5, y: 10 });
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.rotateShapeBy(workingShapes.singleId, 45);
|
||||
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
});
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
},
|
||||
);
|
||||
|
||||
performanceTest("PERF Shape (single): Scale single shape", async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
performanceTest(
|
||||
'PERF Shape (single): Scale single shape',
|
||||
async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
// IMPORTANT: We need to set the click position because we can have
|
||||
// shapes overlapping each other and we need to make sure we click
|
||||
// the right one.
|
||||
await performancePage.selectShape(workingShapes.singleId, { x: 5, y: 10 });
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.scaleShapeBy(workingShapes.singleId, 100, 100);
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
// IMPORTANT: We need to set the click position because we can have
|
||||
// shapes overlapping each other and we need to make sure we click
|
||||
// the right one.
|
||||
await performancePage.selectShape(workingShapes.singleId, { x: 5, y: 10 });
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.scaleShapeBy(workingShapes.singleId, 100, 100);
|
||||
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
});
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
},
|
||||
);
|
||||
|
||||
performanceTest("PERF Shape (multiple): Move multiple shapes", async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
performanceTest(
|
||||
'PERF Shape (multiple): Move multiple shapes',
|
||||
async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectFrame(workingShapes.multipleFrameTitleId);
|
||||
await performancePage.selectShapes(workingShapes.multipleIds);
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.moveSelectedBy(100, 100);
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectFrame(workingShapes.multipleFrameTitleId);
|
||||
await performancePage.selectShapes(workingShapes.multipleIds);
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.moveSelectedBy(100, 100);
|
||||
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
});
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
},
|
||||
);
|
||||
|
||||
performanceTest("PERF Shape (multiple): Rotate multiple shapes", async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
performanceTest(
|
||||
'PERF Shape (multiple): Rotate multiple shapes',
|
||||
async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectFrame(workingShapes.multipleFrameTitleId);
|
||||
await performancePage.selectShapes(workingShapes.multipleIds);
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.rotateSelectedBy(45);
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectFrame(workingShapes.multipleFrameTitleId);
|
||||
await performancePage.selectShapes(workingShapes.multipleIds);
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.rotateSelectedBy(45);
|
||||
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
});
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
},
|
||||
);
|
||||
|
||||
performanceTest("PERF Shape (multiple): Scale multiple shapes", async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
performanceTest(
|
||||
'PERF Shape (multiple): Scale multiple shapes',
|
||||
async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectFrame(workingShapes.multipleFrameTitleId);
|
||||
await performancePage.selectShapes(workingShapes.multipleIds);
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.scaleSelectedBy(100, 100);
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectFrame(workingShapes.multipleFrameTitleId);
|
||||
await performancePage.selectShapes(workingShapes.multipleIds);
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.scaleSelectedBy(100, 100);
|
||||
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
});
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
},
|
||||
);
|
||||
|
||||
performanceTest("PERF Shape (frame): Move frame nested shapes", async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
performanceTest(
|
||||
'PERF Shape (frame): Move frame nested shapes',
|
||||
async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectShape(workingShapes.frameTitleId, { x: 2, y: 2 });
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.moveShapeBy(workingShapes.frameId, 100, 100, {
|
||||
x: 5,
|
||||
y: 50,
|
||||
steps: 100,
|
||||
});
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectShape(workingShapes.frameTitleId, { x: 2, y: 2 });
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.moveShapeBy(workingShapes.frameId, 100, 100, {
|
||||
x: 5,
|
||||
y: 50,
|
||||
steps: 100,
|
||||
});
|
||||
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
});
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
},
|
||||
);
|
||||
|
||||
performanceTest("PERF Shape (frame): Rotate frame nested shapes", async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
performanceTest(
|
||||
'PERF Shape (frame): Rotate frame nested shapes',
|
||||
async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectShape(workingShapes.frameTitleId, {
|
||||
x: 2,
|
||||
y: 2,
|
||||
});
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.rotateShapeBy(workingShapes.frameId, 100, 100, {
|
||||
x: 2,
|
||||
y: 2,
|
||||
steps: 100,
|
||||
});
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectShape(workingShapes.frameTitleId, {
|
||||
x: 2,
|
||||
y: 2,
|
||||
});
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.rotateShapeBy(workingShapes.frameId, 100, 100, {
|
||||
x: 2,
|
||||
y: 2,
|
||||
steps: 100,
|
||||
});
|
||||
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
});
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
},
|
||||
);
|
||||
|
||||
performanceTest("PERF Shape (frame): Scale frame nested shapes", async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
performanceTest(
|
||||
'PERF Shape (frame): Scale frame nested shapes',
|
||||
async ({ page, workingShapes }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectShape(workingShapes.frameTitleId, {
|
||||
x: 2,
|
||||
y: 2,
|
||||
});
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.scaleShapeBy(workingShapes.frameId, 100, 100, {
|
||||
x: 2,
|
||||
y: 2,
|
||||
steps: 100,
|
||||
});
|
||||
await performancePage.selectPage(workingShapes.pageId);
|
||||
await performancePage.selectShape(workingShapes.frameTitleId, {
|
||||
x: 2,
|
||||
y: 2,
|
||||
});
|
||||
await performancePage.zoom(-10, 10);
|
||||
await performancePage.scaleShapeBy(workingShapes.frameId, 100, 100, {
|
||||
x: 2,
|
||||
y: 2,
|
||||
steps: 100,
|
||||
});
|
||||
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
});
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
},
|
||||
);
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
import { expect } from "@playwright/test";
|
||||
import { performanceTest } from "../../fixtures.js";
|
||||
import { PerformancePage } from "../../pages/performance-page";
|
||||
import { expect } from '@playwright/test';
|
||||
import { performanceTest } from '../../fixtures.js';
|
||||
import { PerformancePage } from '../../pages/performance-page';
|
||||
|
||||
performanceTest("PERF Thumbnail renderer", async ({ page }) => {
|
||||
performanceTest('PERF Thumbnail renderer', async ({ page }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.setup();
|
||||
|
||||
// TODO: Medir el tiempo que tarda en renderizar el thumbnail.
|
||||
|
||||
const content = page.locator(".frame-container > .frame-content");
|
||||
await content.waitFor()
|
||||
performance.mark('imposter:start')
|
||||
const content = page.locator('.frame-container > .frame-content');
|
||||
await content.waitFor();
|
||||
performance.mark('imposter:start');
|
||||
|
||||
const imposter = page.locator(".frame-container > .frame-imposter");
|
||||
await imposter.waitFor()
|
||||
performance.mark('imposter:end')
|
||||
const imposter = page.locator('.frame-container > .frame-imposter');
|
||||
await imposter.waitFor();
|
||||
performance.mark('imposter:end');
|
||||
|
||||
const measure = performance.measure('imposter', 'imposter:start', 'imposter:end')
|
||||
console.log(measure.duration, measure.entryType, measure.name)
|
||||
const measure = performance.measure('imposter', 'imposter:start', 'imposter:end');
|
||||
console.log(measure.duration, measure.entryType, measure.name);
|
||||
|
||||
const [averageFrameRate, averageLongTaskDuration] =
|
||||
await performancePage.measure();
|
||||
|
@ -25,4 +25,4 @@ performanceTest("PERF Thumbnail renderer", async ({ page }) => {
|
|||
expect(averageFrameRate).toBeGreaterThan(55);
|
||||
expect(averageFrameRate).toBeLessThan(65);
|
||||
expect(averageLongTaskDuration).toBeLessThan(0.5);
|
||||
})
|
||||
});
|
||||
|
|
|
@ -1,30 +1,29 @@
|
|||
import { expect } from "@playwright/test";
|
||||
import { expect } from '@playwright/test';
|
||||
import { performanceTest } from '../../fixtures.js';
|
||||
import { PerformancePage } from "../../pages/performance-page";
|
||||
import { PerformancePage } from '../../pages/performance-page';
|
||||
|
||||
performanceTest("PERF Viewport: Pan viewport in workspace", async ({ page }) => {
|
||||
performanceTest('PERF Viewport: Pan viewport in workspace', async ({ page }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.waitForPageLoaded();
|
||||
await performancePage.injectFrameRateRecorder();
|
||||
await performancePage.waitForViewportControls();
|
||||
await performancePage.startAll();
|
||||
await performancePage.pan(10, 0, 10)
|
||||
await performancePage.pan(0, 10, 10)
|
||||
await performancePage.pan(-10, 0, 10)
|
||||
await performancePage.pan(0, -10, 10)
|
||||
await performancePage.pan(10, 0, 10);
|
||||
await performancePage.pan(0, 10, 10);
|
||||
await performancePage.pan(-10, 0, 10);
|
||||
await performancePage.pan(0, -10, 10);
|
||||
const [frameRateRecords, longTasksRecords] = await performancePage.stopAll();
|
||||
const averageFrameRate =
|
||||
performancePage.calculateAverageFrameRate(frameRateRecords);
|
||||
console.log("FPS", averageFrameRate);
|
||||
console.log('FPS', averageFrameRate);
|
||||
expect(averageFrameRate).toBeGreaterThan(30);
|
||||
const averageLongTaskDuration =
|
||||
performancePage.calculateAverageLongTaskDuration(longTasksRecords);
|
||||
console.log("LTS", averageLongTaskDuration);
|
||||
console.log('LTS', averageLongTaskDuration);
|
||||
expect(averageLongTaskDuration).toBeLessThan(100);
|
||||
|
||||
});
|
||||
|
||||
performanceTest("PERF Viewport: Zoom viewport in workspace", async ({ page }) => {
|
||||
performanceTest('PERF Viewport: Zoom viewport in workspace', async ({ page }) => {
|
||||
const performancePage = new PerformancePage(page);
|
||||
await performancePage.waitForPageLoaded();
|
||||
await performancePage.injectFrameRateRecorder();
|
||||
|
@ -33,10 +32,12 @@ performanceTest("PERF Viewport: Zoom viewport in workspace", async ({ page }) =>
|
|||
await performancePage.zoom(10, 10);
|
||||
await performancePage.zoom(-10, 10);
|
||||
const [frameRateRecords, longTasksRecords] = await performancePage.stopAll();
|
||||
const averageFrameRate = performancePage.calculateAverageFrameRate(frameRateRecords);
|
||||
console.log("FPS", averageFrameRate);
|
||||
const averageFrameRate =
|
||||
performancePage.calculateAverageFrameRate(frameRateRecords);
|
||||
console.log('FPS', averageFrameRate);
|
||||
expect(averageFrameRate).toBeGreaterThan(30);
|
||||
const averageLongTaskDuration = performancePage.calculateAverageLongTaskDuration(longTasksRecords);
|
||||
console.log("LTS", averageLongTaskDuration);
|
||||
const averageLongTaskDuration =
|
||||
performancePage.calculateAverageLongTaskDuration(longTasksRecords);
|
||||
console.log('LTS', averageLongTaskDuration);
|
||||
expect(averageLongTaskDuration).toBeLessThan(100);
|
||||
});
|
||||
|
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 59 KiB |
146
tests/ui-theme/ui-theme-features-light-mode.spec.js
Normal file
|
@ -0,0 +1,146 @@
|
|||
const { mainTest } = require('../../fixtures');
|
||||
const { MainPage } = require('../../pages/workspace/main-page');
|
||||
const { expect, test } = require('@playwright/test');
|
||||
const { random } = require('../../helpers/string-generator');
|
||||
const { ProfilePage } = require('../../pages/profile-page');
|
||||
const { DashboardPage } = require('../../pages/dashboard/dashboard-page');
|
||||
const { TeamPage } = require('../../pages/dashboard/team-page');
|
||||
const { AssetsPanelPage } = require('../../pages/workspace/assets-panel-page');
|
||||
const { InspectPanelPage } = require('../../pages/workspace/inspect-panel-page');
|
||||
const { ViewModePage } = require('../../pages/workspace/view-mode-page');
|
||||
|
||||
let profilePage,
|
||||
teamPage,
|
||||
dashboardPage,
|
||||
mainPage,
|
||||
assetsPanelPage,
|
||||
inspectPanelPage,
|
||||
viewModePage;
|
||||
const teamName = random().concat('autotest');
|
||||
test.beforeEach(async ({ page }) => {
|
||||
viewModePage = new ViewModePage(page);
|
||||
inspectPanelPage = new InspectPanelPage(page);
|
||||
assetsPanelPage = new AssetsPanelPage(page);
|
||||
profilePage = new ProfilePage(page);
|
||||
teamPage = new TeamPage(page);
|
||||
dashboardPage = new DashboardPage(page);
|
||||
mainPage = new MainPage(page);
|
||||
await teamPage.createTeam(teamName);
|
||||
await teamPage.isTeamSelected(teamName);
|
||||
await profilePage.openYourAccountPage();
|
||||
await profilePage.openSettingsTab();
|
||||
await profilePage.selectLightTheme();
|
||||
});
|
||||
|
||||
test.describe('Settings - UI THEME', () => {
|
||||
mainTest(
|
||||
'1677 Check Projects page' +
|
||||
'1678 Check Fonts page' +
|
||||
'1679 Check Teams page (Settings tab)' +
|
||||
'1680 Check "Your Account" page (Profile tab)',
|
||||
async ({}) => {
|
||||
await profilePage.clickOnProfileTab();
|
||||
await expect(profilePage.profileSection).toHaveScreenshot(
|
||||
'profile-image.png',
|
||||
{
|
||||
mask: [
|
||||
profilePage.profileAvatarBlock,
|
||||
profilePage.profileEmailInput,
|
||||
profilePage.profileNameInput,
|
||||
],
|
||||
},
|
||||
);
|
||||
await profilePage.backToDashboardFromAccount();
|
||||
await expect(dashboardPage.dashboardSection).toHaveScreenshot(
|
||||
'dashboard-image.png',
|
||||
{
|
||||
mask: [profilePage.profileMenuButton, teamPage.teamCurrentNameDiv],
|
||||
},
|
||||
);
|
||||
await dashboardPage.openSidebarItem('Fonts');
|
||||
await expect(teamPage.teamSettingsSection).toHaveScreenshot('fonts-image.png');
|
||||
await teamPage.openTeamSettingsPageViaOptionsMenu();
|
||||
await expect(teamPage.teamSettingsSection).toHaveScreenshot(
|
||||
'team-settings-image.png',
|
||||
{
|
||||
mask: [
|
||||
teamPage.teamIcon,
|
||||
teamPage.teamOwnerSection,
|
||||
teamPage.teamNameLabel,
|
||||
],
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
mainTest(
|
||||
'PENPOT-1681 Check Layers tab' +
|
||||
'PENPOT-1682 Check Design tab' +
|
||||
'PENPOT-1683 Check Assets tab' +
|
||||
'PENPOT-1685 Check Inspect tab',
|
||||
async ({}) => {
|
||||
await profilePage.backToDashboardFromAccount();
|
||||
await dashboardPage.createFileViaPlaceholder();
|
||||
await mainPage.isMainPageLoaded();
|
||||
await mainPage.createDefaultRectangleByCoordinates(300, 300);
|
||||
await mainPage.createComponentViaRightClick();
|
||||
await mainPage.waitForChangeIsSaved();
|
||||
await expect(mainPage.fileLeftSidebarAside).toHaveScreenshot(
|
||||
'layers-file-left-sidebar-image.png',
|
||||
{
|
||||
mask: [mainPage.fileNameSpan],
|
||||
},
|
||||
);
|
||||
await assetsPanelPage.clickAssetsTab();
|
||||
await expect(mainPage.fileLeftSidebarAside).toHaveScreenshot(
|
||||
'assets-file-left-sidebar-image.png',
|
||||
{
|
||||
mask: [mainPage.fileNameSpan],
|
||||
},
|
||||
);
|
||||
await expect(mainPage.fileRightSidebarAside).toHaveScreenshot(
|
||||
'assets-file-right-sidebar-image.png',
|
||||
{
|
||||
mask: [mainPage.usersSection],
|
||||
},
|
||||
);
|
||||
await inspectPanelPage.openInspectTab();
|
||||
await expect(mainPage.fileRightSidebarAside).toHaveScreenshot(
|
||||
'inspect-file-right-sidebar-image.png',
|
||||
{
|
||||
mask: [mainPage.usersSection],
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
mainTest(
|
||||
'PENPOT-1686 Check Inspect tab' + 'PENPOT-1687 Check Interactions tab',
|
||||
async ({}) => {
|
||||
await profilePage.backToDashboardFromAccount();
|
||||
await dashboardPage.createFileViaPlaceholder();
|
||||
await mainPage.isMainPageLoaded();
|
||||
await mainPage.createDefaultBoardByCoordinates(300, 300);
|
||||
await mainPage.waitForChangeIsSaved();
|
||||
const newPage = await viewModePage.clickViewModeButton();
|
||||
viewModePage = new ViewModePage(newPage);
|
||||
await expect(viewModePage.viewerLoyautSection).toHaveScreenshot(
|
||||
'view-mode-page-image.png',
|
||||
{ maxDiffPixelRatio: 0 },
|
||||
);
|
||||
await viewModePage.openInspectTab();
|
||||
await expect(viewModePage.viewerLoyautSection).toHaveScreenshot(
|
||||
'view-mode-inspect-page-image.png',
|
||||
{ maxDiffPixelRatio: 0 },
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test.afterEach(async ({}) => {
|
||||
await profilePage.goToAccountPage();
|
||||
await profilePage.openSettingsTab();
|
||||
await profilePage.selectDarkTheme();
|
||||
await profilePage.backToDashboardFromAccount();
|
||||
await teamPage.deleteTeam(teamName);
|
||||
});
|
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 118 KiB |
After Width: | Height: | Size: 102 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 101 KiB |
After Width: | Height: | Size: 99 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 48 KiB |