import TriggerOptions = Cypress.TriggerOptions;
|
import ObjectLike = Cypress.ObjectLike;
|
import ClickOptions = Cypress.ClickOptions;
|
|
type MouseInteractionOptions = Partial<TriggerOptions & ObjectLike & MouseEvent>;
|
|
export const ImageView = {
|
get image() {
|
cy.log("Get main image");
|
return cy.get("img[alt=LS]");
|
},
|
get root() {
|
return this.image.closest(".lsf-object");
|
},
|
get drawingFrame() {
|
return this.image.closest('[class^="frame--"]');
|
},
|
get drawingArea() {
|
cy.log("Get Konva.js root");
|
return this.drawingFrame.siblings().get('[class^="image-element--"] .konvajs-content');
|
},
|
get toolBar() {
|
cy.log("Get tool bar");
|
return this.root.find(".lsf-toolbar");
|
},
|
get pagination() {
|
return this.root.get('[class^="pagination--"]');
|
},
|
get paginationPrevBtn() {
|
return this.pagination.get(".lsf-pagination__btn_arrow-left:not(.lsf-pagination__btn_arrow-left-double)");
|
},
|
get paginationNextBtn() {
|
return this.pagination.get(".lsf-pagination__btn_arrow-right:not(.lsf-pagination__btn_arrow-right-double)");
|
},
|
waitForImage() {
|
cy.log("Make sure that the image is visible and loaded");
|
this.image.should("be.visible").and((img) => {
|
return expect((img[0] as HTMLImageElement).naturalWidth).to.be.greaterThan(0);
|
});
|
|
this.drawingArea.get("canvas").should("be.visible");
|
},
|
/**
|
* Clicks at the coordinates on the drawing area
|
* @param {number} x
|
* @param {number} y
|
*/
|
clickAt(x: number, y: number, options?: Partial<ClickOptions>) {
|
cy.log(`Click at the image view at (${x}, ${y})`);
|
this.drawingArea.scrollIntoView().click(x, y, options);
|
},
|
/**
|
* Clicks at the relative coordinates on the drawing area
|
* @param {number} x
|
* @param {number} y
|
*/
|
clickAtRelative(x: number, y: number, options?: Partial<ClickOptions>) {
|
this.drawingFrame.then((el) => {
|
const bbox: DOMRect = el[0].getBoundingClientRect();
|
const realX = x * bbox.width;
|
const realY = y * bbox.height;
|
|
this.clickAt(realX, realY, options);
|
});
|
},
|
clickAtStageRelative(x: number, y: number, options?: Partial<ClickOptions>) {
|
this.drawingArea.then((el) => {
|
const bbox: DOMRect = el[0].getBoundingClientRect();
|
const realX = x * bbox.width;
|
const realY = y * bbox.height;
|
|
this.clickAt(realX, realY, options);
|
});
|
},
|
dblClickAt(x, y) {
|
this.drawingArea.scrollIntoView().dblclick(x, y);
|
},
|
dblClickAtRelative(x, y) {
|
this.drawingFrame.then((el) => {
|
const bbox: DOMRect = el[0].getBoundingClientRect();
|
const realX = x * bbox.width;
|
const realY = y * bbox.height;
|
|
this.dblClickAt(realX, realY);
|
});
|
},
|
/**
|
* Draws a rectangle on the drawing area.
|
* It also could be used for some drag and drop interactions for example selecting area or moving existing regions.
|
* @param {number} x
|
* @param {number} y
|
* @param {number} width
|
* @param {number} height
|
*/
|
drawRect(x: number, y: number, width: number, height: number, options: MouseInteractionOptions = {}) {
|
cy.log(`Draw rectangle at (${x}, ${y}) of size ${width}x${height}`);
|
this.drawingArea
|
.scrollIntoView()
|
.trigger("mousedown", x, y, { eventConstructor: "MouseEvent", buttons: 1, ...options })
|
.trigger("mousemove", x + width, y + height, { eventConstructor: "MouseEvent", buttons: 1, ...options })
|
.trigger("mouseup", x + width, y + height, { eventConstructor: "MouseEvent", buttons: 1, ...options });
|
},
|
/**
|
* Draws the rectangle on the drawing area with coordinates and size relative to the drawing area.
|
* It also could be used for some drag and drop interactions for example selecting area or moving existing regions.
|
* @param {number} x
|
* @param {number} y
|
* @param {number} width
|
* @param {number} height
|
*/
|
drawRectRelative(x: number, y: number, width: number, height: number, options: MouseInteractionOptions = {}) {
|
this.drawingFrame.then((el) => {
|
const bbox: DOMRect = el[0].getBoundingClientRect();
|
const realX = x * bbox.width;
|
const realY = y * bbox.height;
|
const realWidth = width * bbox.width;
|
const realHeight = height * bbox.height;
|
|
this.drawRect(realX, realY, realWidth, realHeight, options);
|
});
|
},
|
|
/**
|
* Draws a polygon on the drawing area.
|
* @param {Array<[number, number]>} points
|
* @param {boolean} autoclose
|
* @param {MouseInteractionOptions} options
|
*/
|
drawPolygon(points: [number, number][], autoclose, options: MouseInteractionOptions = {}) {
|
const drawingArea = this.drawingArea.scrollIntoView();
|
if (autoclose) {
|
points = [...points, points[0]];
|
}
|
points.forEach((point, _index) => {
|
drawingArea
|
.trigger("mousemove", point[0], point[1], { eventConstructor: "MouseEvent", ...options })
|
.trigger("mousedown", point[0], point[1], { eventConstructor: "MouseEvent", buttons: 1, ...options })
|
.trigger("mouseup", point[0], point[1], { eventConstructor: "MouseEvent", buttons: 1, ...options });
|
});
|
},
|
|
/**
|
* Draws the polygon on the drawing area with coordinates relative to the drawing area.
|
* @param {Array<[number, number]>} points
|
* @param {boolean} autoclose
|
* @param {MouseInteractionOptions} options
|
*/
|
drawPolygonRelative(points: [number, number][], autoclose, options: MouseInteractionOptions = {}) {
|
this.drawingFrame.then((el) => {
|
const bbox: DOMRect = el[0].getBoundingClientRect();
|
const realPoints = points.map(([x, y]) => [x * bbox.width, y * bbox.height]);
|
|
this.drawPolygon(realPoints, autoclose, options);
|
});
|
},
|
/**
|
* Captures a screenshot of an element to compare later
|
* @param {string} name name of the screenshot
|
*/
|
capture(name: string) {
|
return this.drawingArea.captureScreenshot(name);
|
},
|
|
/**
|
* Captures a new screenshot and compares it to already taken one
|
* Fails if screenshots are identical
|
* @param name name of the screenshot
|
* @param threshold to compare image. It's a relation between original number of pixels vs changed number of pixels
|
*/
|
canvasShouldChange(name: string, threshold = 0.1) {
|
return this.drawingArea.compareScreenshot(name, "shouldChange", { threshold });
|
},
|
|
/**
|
* Captures a new screenshot and compares it to already taken one
|
* Fails if screenshots are different
|
* @param name name of the screenshot
|
* @param threshold to compare image. It's a relation between original number of pixels vs changed number of pixels
|
*/
|
canvasShouldNotChange(name: string, threshold = 0.1) {
|
return this.drawingArea.compareScreenshot(name, "shouldNotChange", { threshold });
|
},
|
selectRect3PointToolByHotkey() {
|
cy.get("body").type("{shift}{R}");
|
},
|
zoomInWithHotkey() {
|
cy.get("body").type("{ctrl}{+}");
|
},
|
zoomOutWithHotkey() {
|
cy.get("body").type("{ctrl}{-}");
|
},
|
|
selectRectangleToolByButton() {
|
this.toolBar
|
.find('[aria-label="rectangle-tool"]')
|
.should("be.visible")
|
.click()
|
.should("have.class", "lsf-tool_active");
|
},
|
|
selectEllipseToolByButton() {
|
this.toolBar
|
.find('[aria-label="ellipse-tool"]')
|
.should("be.visible")
|
.click()
|
.should("have.class", "lsf-tool_active");
|
},
|
|
selectPolygonToolByButton() {
|
this.toolBar.find('[aria-label="polygon-tool"]').should("be.visible").click().should("have.class", "lsf-tool");
|
},
|
|
selectKeypointToolByButton() {
|
this.toolBar
|
.find('[aria-label="key-point-tool"]')
|
.should("be.visible")
|
.click()
|
.should("have.class", "lsf-tool_active");
|
},
|
|
selectBrushToolByButton() {
|
this.toolBar.find('[aria-label="brush-tool"]').should("be.visible").click().should("have.class", "lsf-tool_active");
|
},
|
|
selectMoveToolByButton() {
|
this.toolBar.find('[aria-label="move-tool"]').should("be.visible").click().should("have.class", "lsf-tool_active");
|
},
|
|
rotateLeft() {
|
this.toolBar.find('[aria-label="rotate-left"]').should("be.visible").click();
|
},
|
|
rotateRight() {
|
this.toolBar.find('[aria-label="rotate-right"]').should("be.visible").click();
|
},
|
};
|