Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal : fix for intercepting HTTP calls during page load #185

Open
Badisi opened this issue Dec 3, 2021 · 4 comments
Open

Proposal : fix for intercepting HTTP calls during page load #185

Badisi opened this issue Dec 3, 2021 · 4 comments

Comments

@Badisi
Copy link
Contributor

Badisi commented Dec 3, 2021

While trying to intercept http requests originating from an Angular application, I came accross the following restriction mentionned in the README:

There's one catch though: you can't intercept HTTP calls that are initiated on page load (like in most SPAs), as it requires some setup work that can only be done after the page is loaded (due to limitations in selenium). That means you can just capture requests that were initiated inside a test. If you're fine with that, this plugin might be for you, so read on.

Though, I managed to fix it that way:

// Get the setup function from the interceptor service and inline it
let { setup } = require('wdio-intercept-service/lib/interceptor');
setup = setup
    .toString()
    .replace(/\/\*[\s\S]*?\*\/|\/\/.*/gm, '') // remove comments
    .replace(/\n?\r|\n/gm, '') // remove new lines
    .replace(/\s+/gm, ' '); // remove consecutive white spaces

// Listen for any call to the Angular application
const mock = await browser.mock('http://localhost:4200/**');

// Inject the setup as a script if the call was asking for `index.html`
mock.respond(({ body }) => {
    if ((typeof body === 'string') && body.includes('<body>')) {
        return body.replace('<body>', `<body><script>${setup}; setup(function() {});</script>`);
    }
    return body;
});

The idea behind it, is to inject a script in the index.html root file of the Angular application that will set up the interceptor service before the app is actualing started.


I let you guys decide whether this could be added directly to the library or wrote somewhere in the documentation 😉

@christian-bromann
Copy link
Contributor

Afaik this package was build before WebdriverIO had native mocking capabilities and continues to stay a great alternative for browser tests where Puppeteer and CDP can't be used. Not sure how much it makes sense to use both together, because e.g.:

browser.expectRequest('GET', /\/api\/foo/, 200);

is the same as:

await expect(mock).toBeRequestedWith({
    url: '*/api/foo',
    method: 'GET',                                 // [optional] string | array
    statusCode: 200
})

If this package has some useful functionality that native WebdriverIO APIs don't have I suggest we port them over. What do you think?

@Badisi
Copy link
Contributor Author

Badisi commented Dec 6, 2021

The thing is, I was never able to make toBeRequestedWith work...

Even this simple exemple doesn't work:

const url = 'http://localhost:4200';
const mock = browser.mock(url);
await browser.url(url);
await expect(mock).toBeRequestedWith({ url });

Am I doing something wrong ?

@christian-bromann
Copy link
Contributor

Am I doing something wrong ?

Not sure, is it giving you an error message? Are you using latest WebdriverIO?

@Badisi
Copy link
Contributor Author

Badisi commented Dec 6, 2021

wdio version: v7.16.10

spec

describe('Test', () => {
    it('test', async () => {
        const url = 'http://localhost:4200';
        const mock = browser.mock(url);
        await browser.url(url);
        await expect(mock).toBeRequestedWith({ url });
    });
});

result

[chrome 96.0.4664.55 mac os x #0-0] Expect mock to be called with
Expected: {"url": "http://localhost:4200"}
Received: "was not called"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants