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

CORS issue with XMLHttpRequest AJAX call #1680

Closed
glambert opened this issue Aug 9, 2017 · 10 comments
Closed

CORS issue with XMLHttpRequest AJAX call #1680

glambert opened this issue Aug 9, 2017 · 10 comments
Assignees
Labels
STATE: Auto-locked An issue has been automatically locked by the Lock bot. SYSTEM: hammerhead TYPE: question The issue contains a question that won't be addressed.

Comments

@glambert
Copy link

glambert commented Aug 9, 2017

Are you requesting a feature or reporting a bug?

Reporting a bug (coming from hammerhead.js:8)

What is the current behavior?

An AJAX call with XMLHttpRequest to another domain causes CORS issues and returns a 222 status with no response. We are using nock to mock responses.

What is the expected behavior?

An AJAX call with XMLHttpRequest should return a response even when its from another domain.

How would you reproduce the current behavior (if this is a bug)?

Create a test that goes to a page which does an XMLHttpRequest on an external domain.

We use the following code:

nock(/localhost:910[01]/).get('/available').reply(500);

To put this into context, we have an URL we are polling (https://localhost:9101/available) to get some information, and this is what we want to mock. The code aboves returns a 222 code from hammerhead.js.

Specify your

  • operating system: OSX Sierra (10.12.6)
  • testcafe version: 0.17.0
  • node.js version: 6.11.1
@glambert
Copy link
Author

glambert commented Aug 9, 2017

Continuing on this, when using:

nock(/localhost:910[01]/).get('/available', {
    reqheaders: {
        'Access-Control-Allow-Origin': '*'
    }
}).reply(500);

It simple times out and never returns anything.

@AlexanderMoskovkin AlexanderMoskovkin added SYSTEM: hammerhead TYPE: bug The described behavior is considered as wrong (bug). labels Aug 10, 2017
@miherlosev miherlosev self-assigned this Aug 10, 2017
@miherlosev
Copy link
Collaborator

Hi, @ls-guillaume-lambert .

Specify reply headers instead of reqheaders.
Also need to add the response body.
See https://github.com/node-nock/nock#specifying-reply-headers.

So, you will need to change your code as follows.

nock(/localhost:910[01]/).get('/available').reply(500, 'reply body', {
        'Access-Control-Allow-Origin': '*'
});

Also I've created the example of testcafe with nock integration.

@miherlosev miherlosev added TYPE: question The issue contains a question that won't be addressed. and removed TYPE: bug The described behavior is considered as wrong (bug). labels Aug 10, 2017
@glambert
Copy link
Author

glambert commented Aug 10, 2017

Yup this does work, but when using the .reply(function() { ... }) API I still get the 222 code:

nock(/localhost:910[01]/).get('/available').reply((uri, requestBody) => {
    return [500, 'Error', {
        'Access-Control-Allow-Origin': '*'
    }];
);

This surely has to do with nock:

https://github.com/node-nock/nock/blob/master/lib/interceptor.js#L61

@glambert
Copy link
Author

glambert commented Aug 10, 2017

To put this into context, in our e2e test, we need to change the response when a variable is set. Also note that this a polled XMLHttpRequest:

let isAppInstalled = false;

nock(/localhost:910[01]/).persist().get('/available').reply((uri, requestBody) => {
    return [isAppInstalled ? 200, 500, isAppInstalled ? 'Ok' : 'Error', {
        'Access-Control-Allow-Origin': '*'
    }];
);

test('simple', async t => {
    await t.click('#someSelector');
    // should return 500 with nock
    isAppInstalled = true;
    // should return 200 with nock
    await t.expect(Selector('#installed').exists).ok();
});

So we suspect it has something to do with the way nock is handling the reply method when using a function.

@miherlosev
Copy link
Collaborator

'222' is an internal http status code. Testcafe performs validation of a cross-domain request by itself (see https://github.com/DevExpress/testcafe-hammerhead/blob/master/src/request-pipeline/xhr/same-origin-policy.js).

If a request does not pass CORS rules, the proxy responds with 222 status code.
On the client side, we emulate the native browser behavior: all appropriate getters will return '0' http status code (eg. xhr.statusCode).

In your case, '222' status code means that nock's request mock was configured wrongly and it does not pass CORS rules.
By using .reply((uri, requestBody) => {}, you cannot setup response headers and status code. You just return [500, 'Error', {...}] as a response body.
Try to set the debugger on this line https://github.com/node-nock/nock/blob/master/lib\request_overrider.js#L373 and run your tests.

You can also use a working example from the #1680 (comment).

@glambert
Copy link
Author

Thanks for the response, I will look at debugging this.

If it fails, do you see other ways of achieving we want as mentioned in #1680 (comment)?

@miherlosev
Copy link
Collaborator

I will try to understand why nock does not work.

We planned to do it as build-in feature in the nearest release.
See issues:
#1341
#1271

@glambert
Copy link
Author

Found a way to do it by using .removeInterceptor() and re-defining it:

test('Mock XHR Request changes', async t => {
    const xhrNotInstalledInterceptor = nock(/localhost:910[01]/).persist().get('/available');
    const xhrNotInstalledScope = xhrNotInstalledInterceptor.reply(500, 'Error', {
        'Access-Control-Allow-Origin': '*',
    });

    // Do some expects here
    // ...

   nock.removeInterceptor(xhrNotInstalledInterceptor);

    const xhrInstalledInterceptor = nock(/localhost:910[01]/).persist().get('/available');
    const xhrInstalledScope = xhrInstalledInterceptor.reply(200, 'Success', {
        'Access-Control-Allow-Origin': '*',
    });

    // Do more expects here
    // ...
});

@AlexanderMoskovkin
Copy link
Contributor

closed in favor of #1341 #1271

@lock
Copy link

lock bot commented Mar 28, 2019

This thread has been automatically locked since it is closed and there has not been any recent activity. Please open a new issue for related bugs or feature requests. We recommend you ask TestCafe API, usage and configuration inquiries on StackOverflow.

@lock lock bot added the STATE: Auto-locked An issue has been automatically locked by the Lock bot. label Mar 28, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Mar 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
STATE: Auto-locked An issue has been automatically locked by the Lock bot. SYSTEM: hammerhead TYPE: question The issue contains a question that won't be addressed.
Projects
None yet
Development

No branches or pull requests

3 participants