9

I'm testing the navigation on our website using expect(page.url()).toContain('/nav');. When walking through the code I can clearly see that we hit that url string after the click.

I've tried putting my code into and outside of a promise granting the same error:

Expected substring: "/nav"
Received string:    "https://website.com/about"

      283 |     page.waitForNavigation();
      284 |     await page.hover('nav >> text=Nav');
      285 |     await page.click('nav >> text=Nav');
      286 |     console.log(page.url());
    > 287 |     expect(page.url()).toContain('/nav');
          |                        ^
      288 |
      289 |     page.click('text=Next Nav')
      290 |     expect(page.url()).toContain('/nextNav');

The link itself is a simple <a href="/nav" class="list__item__link" data-v-0df6efc8>Nav</a>.

The console log shows https://website.com/about.

Here's a snippet related to the comments:

////##OURSTORY##////
    page.hover('nav >> text=Our Story');
    page.waitForNavigation();
    await page.click('nav >> text=About');
    expect(page.url()).toContain('story');

    //await page.pause();

    await page.hover('nav >> text=Our Story');
    await page.hover('nav >> text=360° Wellness');
    await page.click('nav >> text=360° Wellness'); 
    console.log(page.url());
    await page.waitForNavigation();
    expect(page.url()).toContain('/360-wellness');
CamdyCorn
  • 121
  • 1
  • 3
  • 9
  • Have you tried converting the url to a string? – Hari Reddy Jul 24 '21 at 21:28
  • If `url()` already returns a string, then perhaps the missing `await` before `page.url()` could solve it? Please let us know if that works. – Hari Reddy Jul 24 '21 at 21:35
  • I added an `await` before the `page.url()` and it didn't help. My IDE even says it's not needed. `page.url()` already converts it to a string, it's a built in functionality. – CamdyCorn Jul 26 '21 at 14:40
  • I see. And you're positive that the url actually has that `/nav` text? have you tested this with `headless: false`? – Hari Reddy Jul 26 '21 at 15:22
  • 1
    Yes, I can confirm. When using `await page.pause()` and stepping through the code I can visibly see the `/nav` in the url and then get the error above. And I always run my tests in `headless: false`. – CamdyCorn Jul 26 '21 at 17:13
  • Hmm, weird. How about trying `expect(page.url()).toBe('https://website.com/nav');` or `toEqual('url-with-nav')`? – Hari Reddy Jul 26 '21 at 20:14
  • Okay, I tried `toBe('https://website.com/nav')` and it yielded the same result. – CamdyCorn Jul 26 '21 at 20:41
  • This is strange. Is the URL you're testing publicly available? If you could share it, perhaps I could try to reproduce it locally and debug. – Hari Reddy Jul 26 '21 at 22:22
  • Sorry it took awhile for me to respond, I was out with the flu. The site is https://ariix.newage.com/ when you hover over "Our Story" at the top in the nav you'll see "360° Wellness", that for some reason has trouble when all the rest work just fine. – CamdyCorn Jul 30 '21 at 15:09
  • I couldn't add my solution here in the comments, so I posted an answer with what worked for me. Do try it out and please let us know if that works for you as well? – Hari Reddy Jul 30 '21 at 18:50
  • Also, I hope you're better health wise now. Excuse me for being insensitive and not inquiring before :P – Hari Reddy Jul 30 '21 at 19:28

3 Answers3

2

Cover it in Promise.all to avoid race condition:

const [response] = await Promise.all([
          page.waitForNavigation(),
          page.click('nav >> text=360° Wellness')
     ]);
    
expect(page.url()).toContain('/360-wellness');

Source: https://playwright.dev/docs/navigations

Vishal Aggarwal
  • 1,929
  • 1
  • 13
  • 23
1

Playwright API for this is waitForURL, like this:

await page.goto('/');
await page.waitForURL('**/auth/login');
mseyfayi
  • 116
  • 5
0

Okay, so I was a little wary of using page.waitForNavigation() from the start, so I gave it a second thought about needing to use it here. Turns out, we don't really need it. Considering load time variations, I added a waitForSelector() which should allow it 30 seconds (or you could do setTimeout to set a custom wait time).

Also, here's a little something about the waitForNavigation() method -

page.waitForNavigation() returns a promise that resolves only after the navigation has finished. The documentation mentions -

In case of navigation to a different anchor or navigation due to History API usage, the navigation will resolve with null.

Since the site development approach can be ambiguous, its perhaps better to steer clear of using the said function. Especially since it also states -

It is useful for when you run code which will indirectly cause the page to navigate

... which in all honesty, I don't clearly understand the use case for.

Anyway, here is what worked; the full test.spec.ts file -

import { Page } from "playwright-core";

describe("Test Suite for a patient random guy on Stack Overflow", () => {
  it("Test Gen: [URL Text] Testing the correct URL path", async () => {
    let page: Page;
    page = await context.newPage();
    await page.goto("https://ariix.newage.com");
    page.hover("nav >> text=Our Story");
    await page.waitForSelector("nav >> text=About");
    await page.click("nav >> text=About");
    console.log(page.url());
    expect(page.url()).toContain("story");
    //await page.pause();
    await page.hover("nav >> text=Our Story");
    await page.waitForSelector("nav >> text=360° Wellness");
    await page.click("nav >> text=360° Wellness");
    console.log(page.url());
    expect(page.url()).toContain("/360-wellness");
  });
});

And it seems to do/print what you were aiming to -

enter image description here

Hopefully this solves this issue at your end. Let us know :)

Hari Reddy
  • 339
  • 3
  • 15