From 48d7eade1226568f2e053c56833bfcdc9a6884d5 Mon Sep 17 00:00:00 2001 From: Zachary Hamm Date: Wed, 15 May 2024 12:33:44 -0400 Subject: [PATCH 1/6] add:update base types on element selector functions to be generic --- src/component.object.ts | 4 ++-- src/types/element.collection.ts | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/component.object.ts b/src/component.object.ts index 1c3b6c2..ca361c5 100644 --- a/src/component.object.ts +++ b/src/component.object.ts @@ -4,10 +4,10 @@ import ElementCollection from "./element.collection"; /** * A component object is useful when building websites using components. * A component can represent a collection of individual element selectors, or even contain - * other nested component objects themselves. + * other nested component objects themselves. It must provide a base container function. */ export default class ComponentObject extends ElementCollection { - constructor(baseContainerFn?: BaseContainerFunction) { + constructor(baseContainerFn: BaseContainerFunction) { super(baseContainerFn); } diff --git a/src/types/element.collection.ts b/src/types/element.collection.ts index 4344cbd..2d5fecf 100644 --- a/src/types/element.collection.ts +++ b/src/types/element.collection.ts @@ -1,11 +1,12 @@ import ElementCollection from "../element.collection"; -export type ElementSelectorFunction = (...params: any) => Cypress.Chainable; - -export type BaseContainerFunction = ElementSelectorFunction; +export type ElementSelectorFunction = ( + ...params: any +) => Cypress.Chainable>; +export type BaseContainerFunction = ElementSelectorFunction; export type Elements = { - [key: string]: ElementSelectorFunction; + [key: string]: ElementSelectorFunction; }; export type ComponentObjectFunction = (instance: ElementCollection | any) => void; From 7631480a7050a374f6364e67cf1c604362139154 Mon Sep 17 00:00:00 2001 From: Zachary Hamm Date: Wed, 15 May 2024 12:33:59 -0400 Subject: [PATCH 2/6] Revert "add:update base types on element selector functions to be generic" This reverts commit 48d7eade1226568f2e053c56833bfcdc9a6884d5. --- src/component.object.ts | 4 ++-- src/types/element.collection.ts | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/component.object.ts b/src/component.object.ts index ca361c5..1c3b6c2 100644 --- a/src/component.object.ts +++ b/src/component.object.ts @@ -4,10 +4,10 @@ import ElementCollection from "./element.collection"; /** * A component object is useful when building websites using components. * A component can represent a collection of individual element selectors, or even contain - * other nested component objects themselves. It must provide a base container function. + * other nested component objects themselves. */ export default class ComponentObject extends ElementCollection { - constructor(baseContainerFn: BaseContainerFunction) { + constructor(baseContainerFn?: BaseContainerFunction) { super(baseContainerFn); } diff --git a/src/types/element.collection.ts b/src/types/element.collection.ts index 2d5fecf..4344cbd 100644 --- a/src/types/element.collection.ts +++ b/src/types/element.collection.ts @@ -1,12 +1,11 @@ import ElementCollection from "../element.collection"; -export type ElementSelectorFunction = ( - ...params: any -) => Cypress.Chainable>; -export type BaseContainerFunction = ElementSelectorFunction; +export type ElementSelectorFunction = (...params: any) => Cypress.Chainable; + +export type BaseContainerFunction = ElementSelectorFunction; export type Elements = { - [key: string]: ElementSelectorFunction; + [key: string]: ElementSelectorFunction; }; export type ComponentObjectFunction = (instance: ElementCollection | any) => void; From f51918b2e0c582863b9db3b798827ae9b8bfc0e7 Mon Sep 17 00:00:00 2001 From: Zachary Hamm Date: Wed, 15 May 2024 12:33:44 -0400 Subject: [PATCH 3/6] add:update base types on element selector functions to be generic --- src/component.object.ts | 4 ++-- src/types/element.collection.ts | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/component.object.ts b/src/component.object.ts index 1c3b6c2..ca361c5 100644 --- a/src/component.object.ts +++ b/src/component.object.ts @@ -4,10 +4,10 @@ import ElementCollection from "./element.collection"; /** * A component object is useful when building websites using components. * A component can represent a collection of individual element selectors, or even contain - * other nested component objects themselves. + * other nested component objects themselves. It must provide a base container function. */ export default class ComponentObject extends ElementCollection { - constructor(baseContainerFn?: BaseContainerFunction) { + constructor(baseContainerFn: BaseContainerFunction) { super(baseContainerFn); } diff --git a/src/types/element.collection.ts b/src/types/element.collection.ts index 4344cbd..2d5fecf 100644 --- a/src/types/element.collection.ts +++ b/src/types/element.collection.ts @@ -1,11 +1,12 @@ import ElementCollection from "../element.collection"; -export type ElementSelectorFunction = (...params: any) => Cypress.Chainable; - -export type BaseContainerFunction = ElementSelectorFunction; +export type ElementSelectorFunction = ( + ...params: any +) => Cypress.Chainable>; +export type BaseContainerFunction = ElementSelectorFunction; export type Elements = { - [key: string]: ElementSelectorFunction; + [key: string]: ElementSelectorFunction; }; export type ComponentObjectFunction = (instance: ElementCollection | any) => void; From 0e2e2622e16dfee2a6320702a14b30337111f215 Mon Sep 17 00:00:00 2001 From: Zachary Hamm Date: Wed, 15 May 2024 12:33:44 -0400 Subject: [PATCH 4/6] v:2.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 35781ab..8865027 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hammzj/cypress-page-object", - "version": "2.2.0", + "version": "2.2.1", "description": "A set of template classes and guides to help with developing component and page objects in Cypress.", "author": "Zachary Hamm ", "license": "MIT", From 5a29a98012c3671c1b878be3b9868a1659ff45a7 Mon Sep 17 00:00:00 2001 From: Zachary Hamm Date: Thu, 16 May 2024 10:13:26 -0400 Subject: [PATCH 5/6] fix:make types a little more generic --- .eslintrc.json | 1 - .gitignore | 3 ++ package.json | 2 +- src/component.object.ts | 7 ++- src/element.collection.ts | 13 +++-- src/types/element.collection.ts | 19 +++++--- tests/cypress/e2e/examples.cy.ts | 84 ++++++++++++++++---------------- 7 files changed, 68 insertions(+), 61 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index b1717f1..6555912 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -29,7 +29,6 @@ }, "ignorePatterns": [ "build", - "cypress", "dist", "node_modules", "**/*.js", diff --git a/.gitignore b/.gitignore index c6bba59..5369603 100644 --- a/.gitignore +++ b/.gitignore @@ -128,3 +128,6 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* + +#Cypress stuff +cypress/screenshots diff --git a/package.json b/package.json index 8865027..22ebb4f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hammzj/cypress-page-object", - "version": "2.2.1", + "version": "2.3.0", "description": "A set of template classes and guides to help with developing component and page objects in Cypress.", "author": "Zachary Hamm ", "license": "MIT", diff --git a/src/component.object.ts b/src/component.object.ts index ca361c5..a19ac63 100644 --- a/src/component.object.ts +++ b/src/component.object.ts @@ -1,4 +1,4 @@ -import { BaseContainerFunction } from "./types"; +import { BaseContainerFunction, Elements, NestedComponents } from "./types"; import ElementCollection from "./element.collection"; /** @@ -7,7 +7,10 @@ import ElementCollection from "./element.collection"; * other nested component objects themselves. It must provide a base container function. */ export default class ComponentObject extends ElementCollection { - constructor(baseContainerFn: BaseContainerFunction) { + protected declare elements: Elements; + protected declare components: NestedComponents; + + constructor(baseContainerFn?: BaseContainerFunction) { super(baseContainerFn); } diff --git a/src/element.collection.ts b/src/element.collection.ts index 7e20e25..d293fe7 100644 --- a/src/element.collection.ts +++ b/src/element.collection.ts @@ -1,4 +1,5 @@ import { BaseContainerFunction, ComponentObjectFunction, Elements, NestedComponents, IMetadata } from "./types"; +import ComponentObject from "./component.object"; /** * Base class for describing page objects and components, which have a collection of element selectors @@ -184,15 +185,13 @@ export default abstract class ElementCollection { * * @example Nesting an element without using this function * //RadioSelectionFormObject - * RadioButtonObject(fn, buttonText) { - * this.elements.form().within(() => fn(new RadioButtonObject(buttonText))); - * } + * RadioButtonObject: (fn, buttonText) => this.elements.form().within(() => fn(new RadioButtonObject(buttonText))); + * */ - //@ts-ignore - performWithin( + performWithin( baseElement: Cypress.Chainable, - nestedComponent: ElementCollection, - fn: ComponentObjectFunction + nestedComponent: TComponentObject, + fn: ComponentObjectFunction ): void { baseElement.within(() => fn(nestedComponent)); } diff --git a/src/types/element.collection.ts b/src/types/element.collection.ts index 2d5fecf..aa8403f 100644 --- a/src/types/element.collection.ts +++ b/src/types/element.collection.ts @@ -1,19 +1,22 @@ -import ElementCollection from "../element.collection"; +import ComponentObject from "../component.object"; -export type ElementSelectorFunction = ( +/* eslint-disable @typescript-eslint/no-explicit-any */ +export type ElementSelectorFunction = ( ...params: any -) => Cypress.Chainable>; -export type BaseContainerFunction = ElementSelectorFunction; +) => Cypress.Chainable>; +export type BaseContainerFunction = ElementSelectorFunction; export type Elements = { + /* eslint-disable @typescript-eslint/no-explicit-any */ [key: string]: ElementSelectorFunction; }; -export type ComponentObjectFunction = (instance: ElementCollection | any) => void; +export type ComponentObjectFunction = (instance: TComponentObject) => void; -export type NestedComponents = { - [key: string]: (fn: ComponentObjectFunction, ...params: any) => void; -}; +export interface NestedComponents { + /* eslint-disable @typescript-eslint/no-explicit-any */ + [key: string]: (fn: ComponentObjectFunction, ...params: any) => void; +} export interface IMetadata { [key: string]: any; diff --git a/tests/cypress/e2e/examples.cy.ts b/tests/cypress/e2e/examples.cy.ts index 4a8a725..01d3286 100644 --- a/tests/cypress/e2e/examples.cy.ts +++ b/tests/cypress/e2e/examples.cy.ts @@ -17,7 +17,7 @@ describe("Element collections", function () { context("Getters", function () { specify("element selectors in `this.elements`", function () { class ExamplePageObject extends PageObject { - public elements: Elements; + public declare elements: Elements; constructor() { super(); @@ -38,7 +38,7 @@ describe("Element collections", function () { specify("finding elements from a parent element selector", function () { class ExamplePageObject extends PageObject { - public elements: Elements; + public declare elements: Elements; constructor() { super(); @@ -58,7 +58,7 @@ describe("Element collections", function () { specify("dynamic element selectors can be parameterized", function () { class ExamplePageObject extends PageObject { - public elements: Elements; + public declare elements: Elements; constructor() { super(); @@ -82,7 +82,7 @@ describe("Element collections", function () { specify("[ALTERNATIVE]: filtering getters instead of using dynamic element selectors", function () { class ExamplePageObject extends PageObject { - public elements: Elements; + public declare elements: Elements; constructor() { super(); @@ -115,7 +115,7 @@ describe("Element collections", function () { specify("component objects are located using a base container function", function () { class ProPricingCardObject extends ComponentObject { - public elements: Elements; + public declare elements: Elements; constructor() { super(() => cy.contains(".MuiCard-root", "Pro")); @@ -185,7 +185,7 @@ describe("Element collections", function () { specify("[ALTERNATE]: base container functions can be updated after creation", function () { //This is useful when properties should be set on an object and saved. class PricingCardObject extends ComponentObject { - public elements: Elements; + public declare elements: Elements; constructor(title: string) { super(); @@ -211,7 +211,7 @@ describe("Element collections", function () { specify("component objects can nested other component objects using performWithin", function () { class PricingHeaderObject extends ComponentObject { - public elements: Elements; + public declare elements: Elements; constructor() { super(() => cy.get(".MuiCardHeader-root")); @@ -224,8 +224,8 @@ describe("Element collections", function () { } class PricingCardObject extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor(title: string) { super(() => { @@ -238,7 +238,7 @@ describe("Element collections", function () { submitButton: () => this.container().find("button"), }; this.addNestedComponents = { - PricingHeaderObject: (fn: ComponentObjectFunction) => + PricingHeaderObject: (fn) => this.performWithin(this.container(), new PricingHeaderObject(), fn), }; } @@ -266,7 +266,7 @@ describe("Element collections", function () { "nested component objects can be added using this.addNestedComponents or this.addComponents", function () { class PricingHeaderObject extends ComponentObject { - public elements: Elements; + public declare elements: Elements; constructor() { super(() => cy.get(".MuiCardHeader-root")); @@ -279,8 +279,8 @@ describe("Element collections", function () { } class PricingCardObject1 extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor(title: string) { super(() => cy.contains(".MuiCardHeader-content", title).parents(".MuiCard-root")); @@ -292,15 +292,15 @@ describe("Element collections", function () { submitButton: () => this.container().find("button"), }; this.addNestedComponents = { - PricingHeaderObject: (fn: ComponentObjectFunction) => + PricingHeaderObject: (fn: ComponentObjectFunction) => this.container().within(() => fn(new PricingHeaderObject())), }; } } class PricingCardObject2 extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor(title: string) { super(() => cy.contains(".MuiCardHeader-content", title).parents(".MuiCard-root")); @@ -312,7 +312,7 @@ describe("Element collections", function () { submitButton: () => this.container().find("button"), }; this.addComponents = { - PricingHeaderObject: (fn: ComponentObjectFunction) => + PricingHeaderObject: (fn) => this.container().within(() => fn(new PricingHeaderObject())), }; } @@ -329,7 +329,7 @@ describe("Element collections", function () { "[ALTERNATIVE]: component objects can nested other component objects using cy.within()", function () { class PricingHeaderObject extends ComponentObject { - public elements: Elements; + public declare elements: Elements; constructor() { super(() => cy.get(".MuiCardHeader-root")); @@ -342,8 +342,8 @@ describe("Element collections", function () { } class PricingCardObject extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor(title: string) { super(() => cy.contains(".MuiCardHeader-content", title).parents(".MuiCard-root")); @@ -356,7 +356,7 @@ describe("Element collections", function () { }; this.addNestedComponents = { - PricingHeaderObject: (fn: ComponentObjectFunction) => + PricingHeaderObject: (fn) => this.container().within(() => fn(new PricingHeaderObject())), }; } @@ -377,7 +377,7 @@ describe("Element collections", function () { specify("nested component objects can be parameterized", function () { class LinkListObject extends ComponentObject { - public elements: Elements; + public declare elements: Elements; constructor(title: string) { super(() => cy.contains(".MuiTypography-h6", title).parent(".MuiGrid-item")); @@ -388,8 +388,8 @@ describe("Element collections", function () { } class FooterObject extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor() { super(() => cy.get(`footer`)); @@ -398,7 +398,7 @@ describe("Element collections", function () { copyright: () => this.container().find(`p.MuiTypography-root`), }; this.addNestedComponents = { - LinkListObject: (fn: ComponentObjectFunction, title: string) => { + LinkListObject: (fn: ComponentObjectFunction, title: string) => { return this.performWithin(this.elements.gridLayout(), new LinkListObject(title), fn); }, }; @@ -425,8 +425,8 @@ describe("Element collections", function () { specify("different indices can change with which nested component is currently being interacted", function () { class LinkListObject extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; //This time, the base container is going to be generically located //So there is a chance for it to find more than one instance. @@ -452,8 +452,8 @@ describe("Element collections", function () { } class FooterObject extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor() { super(() => cy.get(`footer`)); @@ -522,8 +522,8 @@ describe("Element collections", function () { } class FooterObject extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor() { super(() => cy.get(`footer`)); @@ -532,7 +532,7 @@ describe("Element collections", function () { copyright: () => this.container().find(`p.MuiTypography-root`), }; this.addNestedComponents = { - LinkListObject: (fn: ComponentObjectFunction, title: string) => { + LinkListObject: (fn: ComponentObjectFunction, title: string) => { this.performWithin(this.elements.gridLayout(), new LinkListObject(title), fn); }, }; @@ -619,7 +619,7 @@ describe("Element collections", function () { "component objects can extend base classes and add new element selectors using this.addElements", function () { class PricingCardObject extends ComponentObject { - public elements: Elements; + public declare elements: Elements; constructor(title: string) { super(() => { @@ -641,8 +641,8 @@ describe("Element collections", function () { describe("Page objects", function () { class AppBar extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor() { super(() => cy.get(".MuiAppBar-root")); @@ -654,8 +654,8 @@ describe("Element collections", function () { } class PricingHeaderObject extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor() { super(() => cy.get(".MuiCardHeader-root")); @@ -668,8 +668,8 @@ describe("Element collections", function () { } class PricingCardObject extends ComponentObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor(title: string) { super(() => { @@ -708,7 +708,7 @@ describe("Element collections", function () { } class FooterObject extends ComponentObject { - public components: NestedComponents; + public declare components: NestedComponents; constructor() { super(() => cy.get(`footer`)); @@ -729,8 +729,8 @@ describe("Element collections", function () { } class ExamplePageObject extends PageObject { - public elements: Elements; - public components: NestedComponents; + public declare elements: Elements; + public declare components: NestedComponents; constructor() { super(); From f94b2f7c1fbd572f19e8989dcf430341ea34d70d Mon Sep 17 00:00:00 2001 From: Zachary Hamm Date: Thu, 16 May 2024 10:16:54 -0400 Subject: [PATCH 6/6] fix:make types a little more generic --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5369603..760a1ac 100644 --- a/.gitignore +++ b/.gitignore @@ -102,7 +102,6 @@ dist # vuepress v2.x temp and cache directory .temp -.cache # Docusaurus cache and generated files .docusaurus