diff --git a/src/lib/screenshots/types.ts b/src/lib/screenshots/types.ts index 6747fad..cdfb24d 100644 --- a/src/lib/screenshots/types.ts +++ b/src/lib/screenshots/types.ts @@ -66,6 +66,11 @@ export type GlobalVisitOptions = { * @examples ["c8y-drawer-outlet c8y-app-icon .c8y-icon"] */ visitWaitSelector?: string; + /** + * The defaulft style to highlight elements. By default, an organge border of 2px width is used to highlight elements. + * @examples [{ "outline": "2px", "outline-style": "solid", "outline-offset": "-2px", "outline-color": "#FF9300" }, { "border": "2px solid red" }] + */ + highlightStyle?: any; }; export type Screenshot = GlobalVisitOptions & @@ -149,7 +154,7 @@ type ScreenshotSettings = { */ timeouts?: { /** - * The time, in milliseconds, to wait until most DOM based commands are + * The time, in milliseconds, to wait until most DOM based commands are * considered timed out. * @examples [10000] * @default 4000 @@ -172,12 +177,12 @@ type ScreenshotSettings = { * @TJS-type integer */ screenshot?: number; - } + }; }; export type Visit = GlobalVisitOptions & { /** - * The URL to visit. Currently only an URI relative to the base URL is + * The URL to visit. Currently only an URI relative to the base URL is * supported. * @format uri-reference */ @@ -246,40 +251,44 @@ export type WaitAction = { * chainer assertion. * @examples [1000, 10000] */ - wait?: number | { - /** - * The selector of the DOM element to wait for - */ - selector: Selector; - /** - * The timeout in ms to wait for - * @TJS-type integer - * @default 4000 - */ - timeout?: number; - /** - * The chainer assertion to wait for. This translates to a Cypress get().should(). - * See https://docs.cypress.io/api/commands/should - */ - assert?: string | { - /** - * The chainer assertion to. Could be any valid Cypress chainer. The chainer is - * not validated and may or may not have a value to assert. - * @examples ["have.length", "eq", "be.visible"] - */ - chainer: string; - /** - * The value to assert. The value is optional and may not be required by the - * chainer assertion. - */ - value?: string | string[]; - }; - }; + wait?: + | number + | { + /** + * The selector of the DOM element to wait for + */ + selector: Selector; + /** + * The timeout in ms to wait for + * @TJS-type integer + * @default 4000 + */ + timeout?: number; + /** + * The chainer assertion to wait for. This translates to a Cypress get().should(). + * See https://docs.cypress.io/api/commands/should + */ + assert?: + | string + | { + /** + * The chainer assertion to. Could be any valid Cypress chainer. The chainer is + * not validated and may or may not have a value to assert. + * @examples ["have.length", "eq", "be.visible"] + */ + chainer: string; + /** + * The value to assert. The value is optional and may not be required by the + * chainer assertion. + */ + value?: string | string[]; + }; + }; }; export type HighlightActionProperties = { /** - * The selector of the DOM element + * The selector of the DOM element to highlight */ selector: Selector; /** @@ -288,14 +297,17 @@ export type HighlightActionProperties = { */ border?: string; /** - * The CSS styles to apply to the selected element. Use any valid CSS styles. + * The CSS styles to apply to the DOM element. Use any valid CSS styles. * @examples ["background-color: yellow", "outline: dashed", "outline-offset: +3px"] */ styles?: any; }; export type HighlightAction = { - highlight?: HighlightActionProperties | HighlightActionProperties[]; + /** + * Use highlight action to visually highlight a selected DOM element in the screenshot. By default, the element is highlighted with an orange border. Use any valid CSS styles to highlight the element. + */ + highlight?: HighlightActionProperties | HighlightActionProperties[] | string; }; export type ScreenshotClipArea = { @@ -378,9 +390,3 @@ export interface C8yScreenshotOptions { init: boolean; clear: boolean; } - -export type C8yScreenshotActionHandler = ( - action: any, - item: Screenshot, - options: any -) => void; diff --git a/src/screenshot/runner.ts b/src/screenshot/runner.ts index 8b3db82..000d197 100644 --- a/src/screenshot/runner.ts +++ b/src/screenshot/runner.ts @@ -5,7 +5,6 @@ import { pactId } from "../shared/c8ypact"; import { Action, - C8yScreenshotActionHandler, ClickAction, HighlightAction, Screenshot, @@ -23,6 +22,13 @@ import schema from "./schema.json"; const { _ } = Cypress; +export type C8yScreenshotActionHandler = ( + action: any, + that: C8yScreenshotRunner, + item: Screenshot, + options: any +) => void; + export class C8yScreenshotRunner { readonly config: ScreenshotSetup; @@ -189,7 +195,7 @@ export class C8yScreenshotRunner { }; } } - handler(action, item, options); + handler(action, this, item, options); } }); @@ -222,22 +228,38 @@ export class C8yScreenshotRunner { cy.get(selector).type(action.type.value); } - protected highlight(action: HighlightAction) { + protected highlight(action: HighlightAction, that: C8yScreenshotRunner) { const highlights = _.isArray(action.highlight) ? action.highlight : [action.highlight]; highlights?.forEach((highlight) => { - const selector = getSelector(highlight?.selector); - if (selector != null) { - cy.get(selector).then(($element) => { + const selector = getSelector( + _.isString(highlight) ? highlight : highlight?.selector + ); + if (selector == null) return; + + cy.get(selector).then(($element) => { + if (!_.isString(highlight)) { if (highlight?.styles != null) { $element.css(highlight.styles); + return; } else if (highlight?.border != null) { - $element.css("border", highlight.border || "2px solid red"); + $element.css("border", highlight.border); + return; } - }); - } + } + if (that?.config.global?.highlightStyle != null) { + $element.css(that.config.global?.highlightStyle); + } else { + $element.css({ + "outline": "2px", + "outline-style": "solid", + "outline-offset": "-2px", + "outline-color": "#FF9300", + }); + } + }); }); } @@ -283,10 +305,11 @@ export class C8yScreenshotRunner { protected screenshot( action: ScreenshotAction, + _that: C8yScreenshotRunner, item: Screenshot, options: any ) { - let name = action.screenshot?.path || item.image + let name = action.screenshot?.path || item.image; const selector = getSelector(action.screenshot?.selector); cy.task("debug", `Taking screenshot ${name} Selector: ${selector}`); cy.task("debug", `Options: ${JSON.stringify(options)}`); diff --git a/src/screenshot/schema.json b/src/screenshot/schema.json index 7c1db84..113cb8b 100644 --- a/src/screenshot/schema.json +++ b/src/screenshot/schema.json @@ -131,10 +131,10 @@ }, "selector": { "$ref": "#/definitions/Selector", - "description": "The selector of the DOM element" + "description": "The selector of the DOM element to highlight" }, "styles": { - "description": "The CSS styles to apply to the selected element. Use any valid CSS styles.", + "description": "The CSS styles to apply to the DOM element. Use any valid CSS styles.", "examples": [ "background-color: yellow", "outline: dashed", @@ -160,10 +160,10 @@ }, "selector": { "$ref": "#/definitions/Selector", - "description": "The selector of the DOM element" + "description": "The selector of the DOM element to highlight" }, "styles": { - "description": "The CSS styles to apply to the selected element. Use any valid CSS styles.", + "description": "The CSS styles to apply to the DOM element. Use any valid CSS styles.", "examples": [ "background-color: yellow", "outline: dashed", @@ -177,8 +177,12 @@ "type": "object" }, "type": "array" + }, + { + "type": "string" } - ] + ], + "description": "Use highlight action to visually highlight a selected DOM element in the screenshot. By default, the element is highlighted with an orange border. Use any valid CSS styles to highlight the element." } }, "type": "object" @@ -253,7 +257,7 @@ "type": "string" } ], - "description": "The chainer assertion to wait for. This translates to a Cypress get().should(). \nSee https://docs.cypress.io/api/commands/should" + "description": "The chainer assertion to wait for. This translates to a Cypress get().should().\nSee https://docs.cypress.io/api/commands/should" }, "selector": { "$ref": "#/definitions/Selector", @@ -417,10 +421,10 @@ }, "selector": { "$ref": "#/definitions/Selector", - "description": "The selector of the DOM element" + "description": "The selector of the DOM element to highlight" }, "styles": { - "description": "The CSS styles to apply to the selected element. Use any valid CSS styles.", + "description": "The CSS styles to apply to the DOM element. Use any valid CSS styles.", "examples": [ "background-color: yellow", "outline: dashed", @@ -446,10 +450,10 @@ }, "selector": { "$ref": "#/definitions/Selector", - "description": "The selector of the DOM element" + "description": "The selector of the DOM element to highlight" }, "styles": { - "description": "The CSS styles to apply to the selected element. Use any valid CSS styles.", + "description": "The CSS styles to apply to the DOM element. Use any valid CSS styles.", "examples": [ "background-color: yellow", "outline: dashed", @@ -463,8 +467,12 @@ "type": "object" }, "type": "array" + }, + { + "type": "string" } - ] + ], + "description": "Use highlight action to visually highlight a selected DOM element in the screenshot. By default, the element is highlighted with an orange border. Use any valid CSS styles to highlight the element." } }, "type": "object" @@ -539,7 +547,7 @@ "type": "string" } ], - "description": "The chainer assertion to wait for. This translates to a Cypress get().should(). \nSee https://docs.cypress.io/api/commands/should" + "description": "The chainer assertion to wait for. This translates to a Cypress get().should().\nSee https://docs.cypress.io/api/commands/should" }, "selector": { "$ref": "#/definitions/Selector", @@ -586,6 +594,20 @@ "format": "date-time", "type": "string" }, + "highlightStyle": { + "description": "The defaulft style to highlight elements. By default, an organge border of 2px width is used to highlight elements.", + "examples": [ + { + "outline": "2px", + "outline-color": "#FF9300", + "outline-offset": "-2px", + "outline-style": "solid" + }, + { + "border": "2px solid red" + } + ] + }, "image": { "description": "The name of the screenshot image as relative path", "examples": [ @@ -644,7 +666,7 @@ "properties": { "default": { "default": 4000, - "description": "The time, in milliseconds, to wait until most DOM based commands are \nconsidered timed out.", + "description": "The time, in milliseconds, to wait until most DOM based commands are\nconsidered timed out.", "examples": [ 10000 ], @@ -765,6 +787,20 @@ "format": "date-time", "type": "string" }, + "highlightStyle": { + "description": "The defaulft style to highlight elements. By default, an organge border of 2px width is used to highlight elements.", + "examples": [ + { + "outline": "2px", + "outline-color": "#FF9300", + "outline-offset": "-2px", + "outline-style": "solid" + }, + { + "border": "2px solid red" + } + ] + }, "language": { "description": "Load Cumulocity with the given language", "type": "string" @@ -784,7 +820,7 @@ "type": "integer" }, "url": { - "description": "The URL to visit. Currently only an URI relative to the base URL is \nsupported.", + "description": "The URL to visit. Currently only an URI relative to the base URL is\nsupported.", "format": "uri-reference", "type": "string" }, @@ -840,6 +876,20 @@ "description": "When true, prevents JavaScript timers (setTimeout, setInterval, etc)\nand CSS animations from running while the screenshot is taken.", "type": "boolean" }, + "highlightStyle": { + "description": "The defaulft style to highlight elements. By default, an organge border of 2px width is used to highlight elements.", + "examples": [ + { + "outline": "2px", + "outline-color": "#FF9300", + "outline-offset": "-2px", + "outline-style": "solid" + }, + { + "border": "2px solid red" + } + ] + }, "language": { "description": "Load Cumulocity with the given language", "type": "string" @@ -885,7 +935,7 @@ "properties": { "default": { "default": 4000, - "description": "The time, in milliseconds, to wait until most DOM based commands are \nconsidered timed out.", + "description": "The time, in milliseconds, to wait until most DOM based commands are\nconsidered timed out.", "examples": [ 10000 ],