0

I want to go cross domain from one website to another, cypress is letting me do this nicely with the cy.origin() function.

What I also want is to pass my page object model for the page I am on into this function.

I have tried a few ways of instantiating my class and passing as per the documentation into the args. I cannot get it to execute at runtime...

const args = {
    testObject: new MyPageObject()
};

// As the domain has changed we need to use the cy.origin function
cy.origin(dfBaseURL, {
    args: {
        args
    }
}, ({
    args
}) => {

    args.testObject.getContinueButton().click({
        force: true
    });

})

Currently with...

enter image description here

2 Answers2

6

No, I tried this also, you can't do it.

The docs say

Values passed into args must be serializable

Here is my proof of concept

class MyPageObject {
  add() {
    return 1+2
  }
}

it('function serialization with cy.origin', () => {

  const testObject = new MyPageObject()
  
  console.log(typeof testObject.add)         // yields "function"
  console.log(JSON.stringify(testObject))    // yields "{}" - add() has been removed

  cy.origin('https://example.com', { args: { testObject } }, ({testObject}) => {

    console.log(testObject, testObject.add)  // yields "{}" and "undefined"

  })
})

Technically, you can pre-serialize the object and override the default serialization behavior for function properties (turn them into strings as you see in devtools), then use the dreaded "eval" within the cy.origin() to re-instantiate all the methods.

But no, basically page objects are not a good fit with the Cypress paradigm.


Using JSON or object instead

As suggested in the notes, a simple object can be used to pass selectors in.

const selectors = requires('selectors.json')

/* 
 Selectors is an object with string properties, it is serializable
 {
   login: 'input#user-name',
   ...
*/

it('object map of selectors with cy.origin', () => {
  
  console.log(typeof selectors.login)        // yields "string"
  console.log(JSON.stringify(selectors))     // yields "{login: ...}" 

  cy.origin('https://example.com', { args: {selectors} }, ({selectors}) => {

    console.log(JSON.stringify(selectors))   // yields "{login: ...}" 

  })
})
Sitzfleisch
  • 144
  • 5
  • Can I pass a .json file through then with the selectors I want in there? https://stackoverflow.com/questions/66122697/how-to-create-and-call-selectors-from-a-separate-file-in-cypress – user2400852 May 07 '23 at 07:48
  • You certainly can. Only functions (methods) are a problem, because of possible references to variables in the outer scope (closure variables). – Sitzfleisch May 07 '23 at 22:14
  • Thanks, that worked. No page objects for a cy.origin call, just use a .json file full of your selectors. – user2400852 May 08 '23 at 07:59
1

You should probably instantiate your class by replacing

testObject: new MyPageObject

by

testObject: new MyPageObject()
Wandrille
  • 6,267
  • 3
  • 20
  • 43
  • Good spot, let me try that. – user2400852 May 05 '23 at 14:46
  • I'm getting the same error...is it not possible? From Cypress documentation page. Yielding a value Values returned or yielded from the callback function must be serializable or they will not be returned to the primary origin. – user2400852 May 05 '23 at 14:55