playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[BUG] global setup re authentication is not working in the test

Open InduKrish opened this issue 3 years ago • 6 comments

global-setup.js file

const { chromium } = require('@playwright/test');
const LoginPage = require("./pages/loginPage");

module.exports = async config => {
   const {  storageState } = config.projects[0].use;
    const browser = await chromium.launch();
    const page = await browser.newPage();

    const loginPage = new LoginPage(page);
    await loginPage.goTo();
    await loginPage.loginAsIFUser();

    await page
        .context()
        .storageState({ path: 'storageState.json'  })
   await browser.close();
};

playwright-config.js file

const config = {

  globalSetup: require.resolve('./global-setup'),
  //globalSetup: './global-setup',
  use: {
    baseURL: 'https://golden.cbna.dev0.dev.aws.swacorp.com',
    storageState: 'storageState.json',
    trace: 'on-first-retry',
  },

i did setup global file and update config file as well, but the session token is not used by the test and the test fails.

storageState.json file sample

{
  "cookies": [
    {
      "name": "PF",
      "value": "token value",
      "domain": "domain name",
      "path": "/",
      "expires": -1,    ----> is this causing the issue? wondering what -1 is for?
      "httpOnly": true,
      "secure": true,
      "sameSite": "None"
    }
  ],
  "origins": []
}

InduKrish avatar Sep 15 '22 17:09 InduKrish

how does your test look like? If you create a browser or context there yourself, then the storageState does not get applied.

-1 means that the cookie is not expiring.

mxschmitt avatar Sep 15 '22 19:09 mxschmitt

My test is using page object model with fixtures.

is there a recent change that does not let storageState work with browser or context , I did notice that the storage state worked fine few weeks ago even with the browser context. (old code is listed below)

New code:

test.describe(
    "Bid and award Default page verification",
    () => {
        test("Default page verification", async ({
                                                           defaultPage,
                                                           loginPage,

                                                       }) => {
        
            await test.step(
                `Navigate to Defaults Page`,
                async () => {
                    await defaultPage.navigateToVacationBidAward();
                    await defaultPage.navigateToSettingDefaults();
                }
            );

            await test.step(
                `Verify Group Code`,
                async () => {
                    await defaultPage.checkActiveStatus('NEW HIRE', " ");
                    await defaultPage.checkActiveStatus('LINEHOLDER', " ");
                    await defaultPage.checkActiveStatus('ON LEAVE', " ");
                    await defaultPage.checkActiveStatus('TERMINATED, QUIT', " ");
                }
            );
        });
    }
);

class DefaultPage extends BasePage {
    constructor(page, isMob) {
        super(page, isMob);
    }

    async navigateToVacationBidAward() {
        console.log("is mobile view?" + this.isMob)
        if (this.isMob) {
            await this.waitAndClick(hamburger);
            await this.waitFirstClick(bidAward);
        } else {
            return await this.waitFirstClick(bidAward);
        }
    }

 async navigateToSettingDefaults() {
        if (this.isMob) {
            await this.waitFirstClick(settingsDefaults);
        } else {
            await this.waitAndClick(settingsDefaults);
        }
        await expect(this.page).toHaveURL('some url);
    }
}

class BasePage {
  constructor(page, isMob) {
    this.page = page;
    this.isMob = isMob;
  }

  async waitAndClick(selector) {
    await this.page.waitForSelector(selector);
    return await this.page.click(selector);
  }

  async waitFirstClick(selector) {
    await this.page.waitForSelector(selector);
    await this.page.locator(selector).first().click();
  }
}

Fixtures

const base = require("@playwright/test");
const LoginPage = require("../pages/loginPage");
const DefaultPage = require("../pages/defaultPage");
const AuctionPage = require("../pages/auctionPage");
const CreateAuctionPage = require("../pages/createAuctionPage");

const test = base.test.extend({
  loginPage: async ({ page }, use) => {
    await use(new LoginPage(page));
  },
  auctionPage: async ({ page, isMobile }, use) => {
    await use(new AuctionPage(page, isMobile));
  },
  defaultPage: async ({ page , isMobile , browser}, use) => {
    await use(new DefaultPage(page, isMobile, browser));  ---> noticed browser is used here, is this causing the issue? 
  },
  createAuctionPage: async ({ page, isMobile }, use) => {
    await use(new CreateAuctionPage(page, isMobile));
  },
});

module.exports = test;

old code worked earlier(few weeks ago): with context and browser

const {test} = require('@playwright/test');

test.beforeAll(async ({browser}) => {
    const context = await browser.newContext({ignoreHTTPSErrors: true});
    const page = await context.newPage();
    const pageRepo = new PageRepo(page);
    const login = pageRepo.getLoginPage();
    await login.goTo();
    await login.validLogin('username', 'password', page);
    await context.storageState({path: 'state.json'});
    webContext = await browser.newContext({storageState: 'state.json'});

    const pageState = await webContext.newPage();
    const pageRepoState = new PageRepo(pageState);
    auctionPage = pageRepo.getAuctionPage();
    loginPage = pageRepoState.getLoginPage();
    await loginPage.goTo();
    await auctionPage.navigateToDashboard();
    await auctionPage.navigateToAuction();
    await auctionPage.selectVacationAuctionSummary();
})

InduKrish avatar Sep 15 '22 20:09 InduKrish

old code worked earlier(few weeks ago): with context and browser

When it was working a few weeks ago, what did you change since then?

Sorry its too much code to parse which we can't run, we'd need a small repro what is not working or since when its not working to find out if its regression, otherwise we can't act on it.

mxschmitt avatar Sep 16 '22 10:09 mxschmitt

test-integration.zip Attached is the repo that you can refer. You can test with your test urls, and login details.

I added a wait (sleep) to capture storage state after submitting the login form. but didnt help. you can refer the repo.

how does your test look like? If you create a browser or context there yourself, then the storageState does not get applied.

Can you please clarify what you mean by creating a browser or context there yourself in the test? Can you help me with the sample? want to understand the scenario when you say that the storageState does not get applied.

Please let me know if you need any other details.

InduKrish avatar Sep 16 '22 13:09 InduKrish

What did you change since it was working is the main question.

In which browser are you testing?

mxschmitt avatar Sep 20 '22 09:09 mxschmitt

I added fixtures in the new test with the page object models and setup global file. I am testing in chrome browser. I attached the framework that you can refer as well.

New code: test.describe( "Bid and award Default page verification", () => { test("Default page verification", async ({ defaultPage, ---> it is coming from the fixture loginPage,

                                                   }) => {
    
        await test.step(
            `Navigate to Defaults Page`,
            async () => {
                await defaultPage.navigateToVacationBidAward();
                await defaultPage.navigateToSettingDefaults();
            }
        );

        await test.step(
            `Verify Group Code`,
            async () => {
                await defaultPage.checkActiveStatus('NEW HIRE', " ");
                await defaultPage.checkActiveStatus('LINEHOLDER', " ");
                await defaultPage.checkActiveStatus('ON LEAVE', " ");
                await defaultPage.checkActiveStatus('TERMINATED, QUIT', " ");
            }
        );
    });
}

);

old code is setup without any fixtures, it has only page object model and no gloabl setup file like below:

test.beforeAll(async ({browser}) => { const context = await browser.newContext({ignoreHTTPSErrors: true}); const page = await context.newPage(); const pageRepo = new PageRepo(page); const login = pageRepo.getLoginPage(); await login.goTo(); await login.validLogin('username', 'password', page); await context.storageState({path: 'state.json'}); webContext = await browser.newContext({storageState: 'state.json'});

const pageState = await webContext.newPage();
const pageRepoState = new PageRepo(pageState);
auctionPage = pageRepo.getAuctionPage();
loginPage = pageRepoState.getLoginPage();
await loginPage.goTo();
await auctionPage.navigateToDashboard();
await auctionPage.navigateToAuction();
await auctionPage.selectVacationAuctionSummary();

})

now both the old and new code are not working, any reason? is it the application issue? and do you see any issues with the way how i setup global ts file in the new code? can you please advise?

InduKrish avatar Sep 21 '22 16:09 InduKrish

Closing since we can't act on that, we need a clear repro in a git repo or zip file with a version which was working and which one was not. Please re-file if you have that information!

mxschmitt avatar Sep 30 '22 08:09 mxschmitt