msmith1114
msmith1114

Reputation: 3229

JavaScript Classes: storing variables in constructor vs get methods

So I am working on a Automation Framework using Page Object Model pattern as well as Cypress (Which is written in JavaScript).

For portions of the page I am making page components (essentially smaller page objects). To reduce maintenance I want to store "locators" for the web elements for easy access (in case they ever change).

I will be referring to these locators further down in the class in larger methods (that combine multiple elements and do things with them). However Im not sure the best way to store them.

Two options come to mind (Im not an expert at JavaScript so there may be a better way. Anyways there is..

Option 1: (Store them in simple GET methods like so):

saveButton() {
    return cy.contains('Save')
}

nameField() {
    return cy.get('.form-control[name="name"]')
}

descriptionField() {
    return cy.get('.form-control[name="description"]')
}

Then when I need to access the locator I just call nameField().type() or saveButton().click() further down in the class larger methods (Although I guess i'll need to prepend this before them.

The other option would be something like this by using the constructor:

Option 2: (Use the constructor)

class WidgetForm extends PageObject {
    constructor() {
        this.saveButton = 'Save'
        this.nameField = '.form-control[name="name"]'
        this.descriptionField = '.form-control[name="description"]'
    }
//...more code further down that uses these values

I can then refer to them in a similar way such as cy.get(this.nameField).type() although I suppose I could also store the entire Cypress command function in the constructor value such as:

this.nameField = cy.get('.form-control[name="name"]') (At least I assume).

Is there a particular advantage to either? I wish JavaScript allowed constant private values stored in the classes similar to other languages (I know it's coming in ES7 but i'd like to stick with what works now).

Obviously any other suggestions are welcome. For some reason Option 1 looks better to me. But im not sure if it's slower/uglier defining so many functions.

Upvotes: 0

Views: 1108

Answers (1)

Davin
Davin

Reputation: 86

option 1 looks good to me, the organization is more intuitive and the end result looks nicer in my opinion.

Class WidgetForm {

    nameField() {
        return cy.get('.form-control[name="name"]')
    }

}

then in your tests:

beforeEach(function () {
  WidgetForm.nameField().type({"Smith"})
})

not sure if you meant this for your second suggestion, but you could use a getter:

Class WidgetForm extends PageObject{
    constructor() {
        this.saveButton = 'Save'
        this.nameField = '.form-control[name="name"]'
        this.descriptionField = '.form-control[name="description"]'
    }
    get nameField() {
        return cy.get(this.nameField)
    }
}

Upvotes: 2

Related Questions