jest-cucumber icon indicating copy to clipboard operation
jest-cucumber copied to clipboard

shared-steps unable to find page instance

Open lakshmanp21 opened this issue 5 years ago • 5 comments

feature: 
Feature: Upload Feature
    # @test
    Scenario:   I can try common steps
        Given   I am on the landing page ----> this is my common step used in multiple feature files
step_definitions:
import { BrowserTypes } from '../../src/browserTypes';
import * as playwright from 'playwright';

import { loadFeature, defineFeature } from 'jest-cucumber';

import { landing_page } from './shared-steps';

let browser: any;
let page: any;

const feature = loadFeature('./src/features/example.feature');

// Loop over all the supported browsers
for (const browserType of BrowserTypes) {
    defineFeature(feature, (test) => {
        beforeAll(async () => {
            browser = await playwright[browserType].launch({ headless: false }).catch((log: any) => console.log(log));
            page = await browser.newPage().catch((log: any) => console.log(log));
        });
        afterAll(() => {
            // browser.close().catch((log: any) => console.log(log))
        });
        afterEach(async () => {
            // await page.waitFor(3000)
        });
        beforeEach(async () => {
            await page.goto('xxxx.com/', {
                waitUntil: 'networkidle0',
            });
        });

        test('I can try common steps', async ({ given }) => {
            landing_page(given, page);
        });
    });
}
shared-steps.ts

export const landing_page = (given, page) => {
    given(/^I am on the landing page$/, async () => {
        console.log(await page.title());
        expect(await page.title()).toEqual('Sign In');
    });
}
Error:
TypeError: Cannot read property 'title' of undefined

      3 | export const landing_page = (given, page) => {
      4 |     given(/^I am on the landing page$/, async () => {
    > 5 |         console.log(await page.title());
        |                                ^
      6 |         expect(await page.title()).toEqual('Sign In');
      7 |     });
      8 | }

lakshmanp21 avatar Aug 21 '20 10:08 lakshmanp21

I think this is an issue with timing of beforeAll / beforeEach and landing_page getting called to declare your given step. It would probably work better if you declare an object reference like scenarioContext below, and then pass that object into your shared step. That way, you can create and destroy the properties of the top-level object as you like in your hooks, but the shared step will always have a reference to the top-level object that won't be changing.

The docs and examples need to be updated, since the currently recommended pattern can be problematic. Implementing #61 would be ideal, I suppose.

for (const browserType of BrowserTypes) {
    defineFeature(feature, (test) => {
        const scenarioContext = {};

        beforeAll(async () => {
            scenarioContext.browser = await playwright[browserType].launch({ headless: false }).catch((log: any) => console.log(log));
            scenarioContext.page = await browser.newPage().catch((log: any) => console.log(log));
        });
        afterAll(() => {
            // scenarioContext.browser.close().catch((log: any) => console.log(log))
        });
        afterEach(async () => {
            // await scenarioContext.page.waitFor(3000)
        });
        beforeEach(async () => {
            await scenarioContext.page.goto('xxxx.com/', {
                waitUntil: 'networkidle0',
            });
        });

        test('I can try common steps', async ({ given }) => {
            landing_page(given, scenarioContext);
        });
    });
}

bencompton avatar Aug 21 '20 17:08 bencompton

unable to identify the step_definition from shared file, calling the function in steps file @bencompton image

lakshmanp21 avatar Oct 05 '20 13:10 lakshmanp21

@bencompton , tried the above example, didn't work. Any update or insight on this please ?

lakshmanp21 avatar Oct 21 '20 14:10 lakshmanp21

@lakshmanp21 you should check out cucumber-jest. it's a transformer for jest that allows you to use the cucumber api with jest. Because it's using the cucumber js api, it supports declaring step definitions once and they can be used in any feature file.

mainfraame avatar Dec 05 '20 21:12 mainfraame

@lakshmanp21 you should check out cucumber-jest. it's a transformer for jest that allows you to use the cucumber api with jest. Because it's using the cucumber js api, it supports declaring step definitions once and they can be used in any feature file.

I am using cucumber-jest as suggested, though the issue (above) exists "dependencies": { "allure-jasmine": "^2.0.0-beta.8", "allure-js-commons": "^2.0.0-beta.8", "codeceptjs": "^2.6.10", "jest": "^26.6.1", "jest-cucumber": "^3.0.0", "playwright": "1.4.0", "ts-jest": "^26.4.3", "typescript": "^3.9.7" }, "devDependencies": { "@fast-csv/parse": "^4.3.3", "@testing-library/jasmine-dom": "^1.1.0", "@types/faker": "^4.1.12", "@types/jest": "^26.0.15", "@types/node": "^14.14.6", "csv-writer": "^1.6.0", "faker": "^4.1.0", "jest-allure": "^0.1.3", "jest-allure2": "^1.2.3", "moment": "^2.28.0" }

lakshmanp21 avatar Dec 08 '20 10:12 lakshmanp21