Pass data from one step to the next synchronously












1















Running Cypress 3.1.1 with cypress-cucumber-preprocessor 1.5.1. I need to pass some static data from one step to another (in the same scenario/test). I can do this using an alias, like this:
cy.wrap(someString).as('myString'), but then I have to access it asynchronously:



cy.get('@myString').then(myString => ...)



This is rather cumbersome, particularly when I have to pass multiple values, requiring multiple wrapped closures, for no apparent benefit. (Currently I'm working around this by aliasing an object, but I shouldn't need to do this.)



How can I pass primitive values from one step to another synchronously?



I thought I might be able to simply set this.myString='' to set the value on the Mocha shared context object, but in that case, the property exists but is set to undefined when accessed in later steps.



Even creating my own context variable with let outside of the step definition does not work. Is this simply a limitation of Cypress and/or the cypress-cucumber-preprocessor?










share|improve this question























  • I am unsure if this should be a comment or not, but I feel like you have to use .its and .invoke to do this with any measure of control. docs.cypress.io/api/commands/invoke.html#Examples docs.cypress.io/api/commands/its.html#Requests

    – Phillipe Bojorquez
    Nov 28 '18 at 2:22


















1















Running Cypress 3.1.1 with cypress-cucumber-preprocessor 1.5.1. I need to pass some static data from one step to another (in the same scenario/test). I can do this using an alias, like this:
cy.wrap(someString).as('myString'), but then I have to access it asynchronously:



cy.get('@myString').then(myString => ...)



This is rather cumbersome, particularly when I have to pass multiple values, requiring multiple wrapped closures, for no apparent benefit. (Currently I'm working around this by aliasing an object, but I shouldn't need to do this.)



How can I pass primitive values from one step to another synchronously?



I thought I might be able to simply set this.myString='' to set the value on the Mocha shared context object, but in that case, the property exists but is set to undefined when accessed in later steps.



Even creating my own context variable with let outside of the step definition does not work. Is this simply a limitation of Cypress and/or the cypress-cucumber-preprocessor?










share|improve this question























  • I am unsure if this should be a comment or not, but I feel like you have to use .its and .invoke to do this with any measure of control. docs.cypress.io/api/commands/invoke.html#Examples docs.cypress.io/api/commands/its.html#Requests

    – Phillipe Bojorquez
    Nov 28 '18 at 2:22
















1












1








1








Running Cypress 3.1.1 with cypress-cucumber-preprocessor 1.5.1. I need to pass some static data from one step to another (in the same scenario/test). I can do this using an alias, like this:
cy.wrap(someString).as('myString'), but then I have to access it asynchronously:



cy.get('@myString').then(myString => ...)



This is rather cumbersome, particularly when I have to pass multiple values, requiring multiple wrapped closures, for no apparent benefit. (Currently I'm working around this by aliasing an object, but I shouldn't need to do this.)



How can I pass primitive values from one step to another synchronously?



I thought I might be able to simply set this.myString='' to set the value on the Mocha shared context object, but in that case, the property exists but is set to undefined when accessed in later steps.



Even creating my own context variable with let outside of the step definition does not work. Is this simply a limitation of Cypress and/or the cypress-cucumber-preprocessor?










share|improve this question














Running Cypress 3.1.1 with cypress-cucumber-preprocessor 1.5.1. I need to pass some static data from one step to another (in the same scenario/test). I can do this using an alias, like this:
cy.wrap(someString).as('myString'), but then I have to access it asynchronously:



cy.get('@myString').then(myString => ...)



This is rather cumbersome, particularly when I have to pass multiple values, requiring multiple wrapped closures, for no apparent benefit. (Currently I'm working around this by aliasing an object, but I shouldn't need to do this.)



How can I pass primitive values from one step to another synchronously?



I thought I might be able to simply set this.myString='' to set the value on the Mocha shared context object, but in that case, the property exists but is set to undefined when accessed in later steps.



Even creating my own context variable with let outside of the step definition does not work. Is this simply a limitation of Cypress and/or the cypress-cucumber-preprocessor?







cucumberjs cypress






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 '18 at 20:17









hackelhackel

634716




634716













  • I am unsure if this should be a comment or not, but I feel like you have to use .its and .invoke to do this with any measure of control. docs.cypress.io/api/commands/invoke.html#Examples docs.cypress.io/api/commands/its.html#Requests

    – Phillipe Bojorquez
    Nov 28 '18 at 2:22





















  • I am unsure if this should be a comment or not, but I feel like you have to use .its and .invoke to do this with any measure of control. docs.cypress.io/api/commands/invoke.html#Examples docs.cypress.io/api/commands/its.html#Requests

    – Phillipe Bojorquez
    Nov 28 '18 at 2:22



















I am unsure if this should be a comment or not, but I feel like you have to use .its and .invoke to do this with any measure of control. docs.cypress.io/api/commands/invoke.html#Examples docs.cypress.io/api/commands/its.html#Requests

– Phillipe Bojorquez
Nov 28 '18 at 2:22







I am unsure if this should be a comment or not, but I feel like you have to use .its and .invoke to do this with any measure of control. docs.cypress.io/api/commands/invoke.html#Examples docs.cypress.io/api/commands/its.html#Requests

– Phillipe Bojorquez
Nov 28 '18 at 2:22














2 Answers
2






active

oldest

votes


















0














This not a complete answer, but you can set javascript variables in a before(() => {}) statement, and they will be available to use within any nested it(..., () => {}) statements.



For example, I have one set of tests checking two versions of the same app written in different frameworks. So I need to know the framework being tested, and load different fixtures.



To do this I use the following



const framework = Cypress.env('FRAMEWORK')
let config;

before(function() {
cy.fixture('frameworks').then(fixture => {
config = fixture[framework]
})
})


Then I can use config in tests,



cy.visit(config.pageUrl)

it('should have a title', () => {
cy.title().should('contain', config.title)
});


You can use before() in many places in the test suite, generally after a describe() or context() and the variables defined within are available in a 'normal' javascript way.






share|improve this answer
























  • Thanks, but I don't believe the before() hook is supported in cypress-cucumber-preprocessor step definitions. Unfortunately declaring the variable outside (like you did with config) doesn't work in this case.

    – hackel
    Nov 27 '18 at 21:35











  • That must cramp your style somewhat. What about given()?

    – Hiram K. Hackenbacker
    Dec 2 '18 at 10:02



















0














Here is a slightly more complicated (and not fully tested) method. A custom command can be added to save values to a global object.



In the Cypress test runner, all the tests seem to run sequentially, but you may have to be careful if using CI and parallel execution.



In /support/commands.js



export const testStore = {}

Cypress.Commands.add('saveAs', { prevSubject: true }, (value, propName) => {
console.log('saveAs', value, propName)
testStore[propName] = value;
return value;
})


In myTest.spec.js



import { testStore } from '../support/commands.js'
...

it('should have a title', () => {
cy.title()
.saveAs('title') // save for next test
.should('contain', 'myTitle) // this test's expectation
});

it('should test something else', () => {
cy.get('.myElement').contains(testStore.title);
});





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382024%2fpass-data-from-one-step-to-the-next-synchronously%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    This not a complete answer, but you can set javascript variables in a before(() => {}) statement, and they will be available to use within any nested it(..., () => {}) statements.



    For example, I have one set of tests checking two versions of the same app written in different frameworks. So I need to know the framework being tested, and load different fixtures.



    To do this I use the following



    const framework = Cypress.env('FRAMEWORK')
    let config;

    before(function() {
    cy.fixture('frameworks').then(fixture => {
    config = fixture[framework]
    })
    })


    Then I can use config in tests,



    cy.visit(config.pageUrl)

    it('should have a title', () => {
    cy.title().should('contain', config.title)
    });


    You can use before() in many places in the test suite, generally after a describe() or context() and the variables defined within are available in a 'normal' javascript way.






    share|improve this answer
























    • Thanks, but I don't believe the before() hook is supported in cypress-cucumber-preprocessor step definitions. Unfortunately declaring the variable outside (like you did with config) doesn't work in this case.

      – hackel
      Nov 27 '18 at 21:35











    • That must cramp your style somewhat. What about given()?

      – Hiram K. Hackenbacker
      Dec 2 '18 at 10:02
















    0














    This not a complete answer, but you can set javascript variables in a before(() => {}) statement, and they will be available to use within any nested it(..., () => {}) statements.



    For example, I have one set of tests checking two versions of the same app written in different frameworks. So I need to know the framework being tested, and load different fixtures.



    To do this I use the following



    const framework = Cypress.env('FRAMEWORK')
    let config;

    before(function() {
    cy.fixture('frameworks').then(fixture => {
    config = fixture[framework]
    })
    })


    Then I can use config in tests,



    cy.visit(config.pageUrl)

    it('should have a title', () => {
    cy.title().should('contain', config.title)
    });


    You can use before() in many places in the test suite, generally after a describe() or context() and the variables defined within are available in a 'normal' javascript way.






    share|improve this answer
























    • Thanks, but I don't believe the before() hook is supported in cypress-cucumber-preprocessor step definitions. Unfortunately declaring the variable outside (like you did with config) doesn't work in this case.

      – hackel
      Nov 27 '18 at 21:35











    • That must cramp your style somewhat. What about given()?

      – Hiram K. Hackenbacker
      Dec 2 '18 at 10:02














    0












    0








    0







    This not a complete answer, but you can set javascript variables in a before(() => {}) statement, and they will be available to use within any nested it(..., () => {}) statements.



    For example, I have one set of tests checking two versions of the same app written in different frameworks. So I need to know the framework being tested, and load different fixtures.



    To do this I use the following



    const framework = Cypress.env('FRAMEWORK')
    let config;

    before(function() {
    cy.fixture('frameworks').then(fixture => {
    config = fixture[framework]
    })
    })


    Then I can use config in tests,



    cy.visit(config.pageUrl)

    it('should have a title', () => {
    cy.title().should('contain', config.title)
    });


    You can use before() in many places in the test suite, generally after a describe() or context() and the variables defined within are available in a 'normal' javascript way.






    share|improve this answer













    This not a complete answer, but you can set javascript variables in a before(() => {}) statement, and they will be available to use within any nested it(..., () => {}) statements.



    For example, I have one set of tests checking two versions of the same app written in different frameworks. So I need to know the framework being tested, and load different fixtures.



    To do this I use the following



    const framework = Cypress.env('FRAMEWORK')
    let config;

    before(function() {
    cy.fixture('frameworks').then(fixture => {
    config = fixture[framework]
    })
    })


    Then I can use config in tests,



    cy.visit(config.pageUrl)

    it('should have a title', () => {
    cy.title().should('contain', config.title)
    });


    You can use before() in many places in the test suite, generally after a describe() or context() and the variables defined within are available in a 'normal' javascript way.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 19 '18 at 22:00









    Hiram K. HackenbackerHiram K. Hackenbacker

    33717




    33717













    • Thanks, but I don't believe the before() hook is supported in cypress-cucumber-preprocessor step definitions. Unfortunately declaring the variable outside (like you did with config) doesn't work in this case.

      – hackel
      Nov 27 '18 at 21:35











    • That must cramp your style somewhat. What about given()?

      – Hiram K. Hackenbacker
      Dec 2 '18 at 10:02



















    • Thanks, but I don't believe the before() hook is supported in cypress-cucumber-preprocessor step definitions. Unfortunately declaring the variable outside (like you did with config) doesn't work in this case.

      – hackel
      Nov 27 '18 at 21:35











    • That must cramp your style somewhat. What about given()?

      – Hiram K. Hackenbacker
      Dec 2 '18 at 10:02

















    Thanks, but I don't believe the before() hook is supported in cypress-cucumber-preprocessor step definitions. Unfortunately declaring the variable outside (like you did with config) doesn't work in this case.

    – hackel
    Nov 27 '18 at 21:35





    Thanks, but I don't believe the before() hook is supported in cypress-cucumber-preprocessor step definitions. Unfortunately declaring the variable outside (like you did with config) doesn't work in this case.

    – hackel
    Nov 27 '18 at 21:35













    That must cramp your style somewhat. What about given()?

    – Hiram K. Hackenbacker
    Dec 2 '18 at 10:02





    That must cramp your style somewhat. What about given()?

    – Hiram K. Hackenbacker
    Dec 2 '18 at 10:02













    0














    Here is a slightly more complicated (and not fully tested) method. A custom command can be added to save values to a global object.



    In the Cypress test runner, all the tests seem to run sequentially, but you may have to be careful if using CI and parallel execution.



    In /support/commands.js



    export const testStore = {}

    Cypress.Commands.add('saveAs', { prevSubject: true }, (value, propName) => {
    console.log('saveAs', value, propName)
    testStore[propName] = value;
    return value;
    })


    In myTest.spec.js



    import { testStore } from '../support/commands.js'
    ...

    it('should have a title', () => {
    cy.title()
    .saveAs('title') // save for next test
    .should('contain', 'myTitle) // this test's expectation
    });

    it('should test something else', () => {
    cy.get('.myElement').contains(testStore.title);
    });





    share|improve this answer




























      0














      Here is a slightly more complicated (and not fully tested) method. A custom command can be added to save values to a global object.



      In the Cypress test runner, all the tests seem to run sequentially, but you may have to be careful if using CI and parallel execution.



      In /support/commands.js



      export const testStore = {}

      Cypress.Commands.add('saveAs', { prevSubject: true }, (value, propName) => {
      console.log('saveAs', value, propName)
      testStore[propName] = value;
      return value;
      })


      In myTest.spec.js



      import { testStore } from '../support/commands.js'
      ...

      it('should have a title', () => {
      cy.title()
      .saveAs('title') // save for next test
      .should('contain', 'myTitle) // this test's expectation
      });

      it('should test something else', () => {
      cy.get('.myElement').contains(testStore.title);
      });





      share|improve this answer


























        0












        0








        0







        Here is a slightly more complicated (and not fully tested) method. A custom command can be added to save values to a global object.



        In the Cypress test runner, all the tests seem to run sequentially, but you may have to be careful if using CI and parallel execution.



        In /support/commands.js



        export const testStore = {}

        Cypress.Commands.add('saveAs', { prevSubject: true }, (value, propName) => {
        console.log('saveAs', value, propName)
        testStore[propName] = value;
        return value;
        })


        In myTest.spec.js



        import { testStore } from '../support/commands.js'
        ...

        it('should have a title', () => {
        cy.title()
        .saveAs('title') // save for next test
        .should('contain', 'myTitle) // this test's expectation
        });

        it('should test something else', () => {
        cy.get('.myElement').contains(testStore.title);
        });





        share|improve this answer













        Here is a slightly more complicated (and not fully tested) method. A custom command can be added to save values to a global object.



        In the Cypress test runner, all the tests seem to run sequentially, but you may have to be careful if using CI and parallel execution.



        In /support/commands.js



        export const testStore = {}

        Cypress.Commands.add('saveAs', { prevSubject: true }, (value, propName) => {
        console.log('saveAs', value, propName)
        testStore[propName] = value;
        return value;
        })


        In myTest.spec.js



        import { testStore } from '../support/commands.js'
        ...

        it('should have a title', () => {
        cy.title()
        .saveAs('title') // save for next test
        .should('contain', 'myTitle) // this test's expectation
        });

        it('should test something else', () => {
        cy.get('.myElement').contains(testStore.title);
        });






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 19 '18 at 22:47









        Hiram K. HackenbackerHiram K. Hackenbacker

        33717




        33717






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382024%2fpass-data-from-one-step-to-the-next-synchronously%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            鏡平學校

            ꓛꓣだゔៀៅຸ໢ທຮ໕໒ ,ໂ'໥໓າ໼ឨឲ៵៭ៈゎゔit''䖳𥁄卿' ☨₤₨こゎもょの;ꜹꟚꞖꞵꟅꞛေၦေɯ,ɨɡ𛃵𛁹ޝ޳ޠ޾,ޤޒޯ޾𫝒𫠁သ𛅤チョ'サノބޘދ𛁐ᶿᶇᶀᶋᶠ㨑㽹⻮ꧬ꧹؍۩وَؠ㇕㇃㇪ ㇦㇋㇋ṜẰᵡᴠ 軌ᵕ搜۳ٰޗޮ޷ސޯ𫖾𫅀ल, ꙭ꙰ꚅꙁꚊꞻꝔ꟠Ꝭㄤﺟޱސꧨꧼ꧴ꧯꧽ꧲ꧯ'⽹⽭⾁⿞⼳⽋២៩ញណើꩯꩤ꩸ꩮᶻᶺᶧᶂ𫳲𫪭𬸄𫵰𬖩𬫣𬊉ၲ𛅬㕦䬺𫝌𫝼,,𫟖𫞽ហៅ஫㆔ాఆఅꙒꚞꙍ,Ꙟ꙱エ ,ポテ,フࢰࢯ𫟠𫞶 𫝤𫟠ﺕﹱﻜﻣ𪵕𪭸𪻆𪾩𫔷ġ,ŧآꞪ꟥,ꞔꝻ♚☹⛵𛀌ꬷꭞȄƁƪƬșƦǙǗdžƝǯǧⱦⱰꓕꓢႋ神 ဴ၀க௭எ௫ឫោ ' េㇷㇴㇼ神ㇸㇲㇽㇴㇼㇻㇸ'ㇸㇿㇸㇹㇰㆣꓚꓤ₡₧ ㄨㄟ㄂ㄖㄎ໗ツڒذ₶।ऩछएोञयूटक़कयँृी,冬'𛅢𛅥ㇱㇵㇶ𥄥𦒽𠣧𠊓𧢖𥞘𩔋цѰㄠſtʯʭɿʆʗʍʩɷɛ,əʏダヵㄐㄘR{gỚṖḺờṠṫảḙḭᴮᵏᴘᵀᵷᵕᴜᴏᵾq﮲ﲿﴽﭙ軌ﰬﶚﶧ﫲Ҝжюїкӈㇴffצּ﬘﭅﬈軌'ffistfflſtffतभफɳɰʊɲʎ𛁱𛁖𛁮𛀉 𛂯𛀞నఋŀŲ 𫟲𫠖𫞺ຆຆ ໹້໕໗ๆทԊꧢꧠ꧰ꓱ⿝⼑ŎḬẃẖỐẅ ,ờỰỈỗﮊDžȩꭏꭎꬻ꭮ꬿꭖꭥꭅ㇭神 ⾈ꓵꓑ⺄㄄ㄪㄙㄅㄇstA۵䞽ॶ𫞑𫝄㇉㇇゜軌𩜛𩳠Jﻺ‚Üမ႕ႌႊၐၸဓၞၞၡ៸wyvtᶎᶪᶹစဎ꣡꣰꣢꣤ٗ؋لㇳㇾㇻㇱ㆐㆔,,㆟Ⱶヤマފ޼ޝަݿݞݠݷݐ',ݘ,ݪݙݵ𬝉𬜁𫝨𫞘くせぉて¼óû×ó£…𛅑הㄙくԗԀ5606神45,神796'𪤻𫞧ꓐ㄁ㄘɥɺꓵꓲ3''7034׉ⱦⱠˆ“𫝋ȍ,ꩲ軌꩷ꩶꩧꩫఞ۔فڱێظペサ神ナᴦᵑ47 9238їﻂ䐊䔉㠸﬎ffiﬣ,לּᴷᴦᵛᵽ,ᴨᵤ ᵸᵥᴗᵈꚏꚉꚟ⻆rtǟƴ𬎎

            Guess what letter conforming each word