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

Role has a large delay/wait after page load #3460

Closed
inctec-leo opened this issue Feb 15, 2019 · 10 comments
Closed

Role has a large delay/wait after page load #3460

inctec-leo opened this issue Feb 15, 2019 · 10 comments
Assignees
Milestone

Comments

@inctec-leo
Copy link

inctec-leo commented Feb 15, 2019

Thanks for this great tool! I am experiencing a long delay when I am trying to use a Role to create a login token.

What is your Test Scenario?

I want to use Role to create a login token.

What is the Current behavior?

Using a Role is taking unreasonably long after page load (>15 sec). Though the same code takes less than a second after page load when run as a test case.

What is the Expected behavior?

After page load, the Role callback should start right away, but it takes more than 15 seconds.

What is your web application and your TestCafe test code?

I have a simple form with mail and password fields, and a submit button. The submit button makes a post request, which I am mocking using nock. I am using node to serve the page.

The following test code takes overall 9 seconds, and less than a second after page load:
 fixture(`Login Page`)
    .page('http://localhost:8080/login');

test('The user sends correct login information and is being logged in', async t => {

    nock('http://localhost:8080')
        .post('/auth/login')
        .reply(200, { "token": "testtoken" });
    await t.typeText('#login-email', 'email');
    await t.typeText('#login-password', 'password');
    await t.click('#login-button');
    await t.expect(JSON.parse(await localStorageGet('user'))).eql({ token: 'testtoken' });
});

If I run the code as a role, there is a waiting time of 15-17 seconds after the login page was loaded. This is the role:

export const authUserRole = Role('http://localhost:8080/login', async t => {

    console.log('Creating mock request');
    nock('http://localhost:8080')
        .post('/auth/login')
        .reply(200, { "token": "testtoken" });

    await t.typeText('#login-email', 'email');
    await t.typeText('#login-password', 'password');
    await t.click('#login-button');
});

This is how I am calling the role:

fixture(`Main Page`)
    .page('http://localhost:8080/');

test('When logged in the user sees the list of stories', async t => {
   // This line of code takes more than 15 seconds
    await t.useRole(authUserRole);
});
 
Your complete test report:

This is the test report for an empty test using the Rule

Debugger listening on ws://127.0.0.1:48976/1adecede-0152-4071-b869-eb5fa5ea3a46
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
 Running tests in:
 - Chrome 72.0.3626 / Linux 0.0.0

 Main Page
(node:32646) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
 ✓ When logged in the user sees the list of stories


 1 passed (37s)
Waiting for the debugger to disconnect...
[1]    32646 killed     /usr/bin/node --inspect-brk=48976 node_modules/testcafe/bin/testcafe.js chrom

Steps to Reproduce:

Your Environment details:

  • testcafe version: 1.0.1
  • node.js version: 11.6.0
  • command-line arguments: chrome
  • browser name and version: Chrome: 72.0.3626.81, Firefox: 65.0
  • platform and version: Ubuntu 18.04.1 kernel 4.15.0-43-generic
  • other:

EDIT: I just had the chance to run the test on Mac with Chrome, and the waiting time was significantly less, though there was still a recognizable delay of around 2-3 seconds after page load.

@need-response-app need-response-app bot added the STATE: Need response An issue that requires a response or attention from the team. label Feb 15, 2019
@AlexKamaev
Copy link
Contributor

I've looked at your test code and at it seems valid to me. I would appreciate if you share your project with me. In this case, I'll be able to determine the cause of the issue more efficiently.
In addition, I want to mention that TestCafe has its own mechanism of mocking HTTP requests.
Please refer to this article: https://devexpress.github.io/testcafe/documentation/test-api/intercepting-http-requests/

@AlexKamaev AlexKamaev added STATE: Need clarification An issue lacks information for further research. and removed STATE: Need response An issue that requires a response or attention from the team. labels Feb 18, 2019
@inctec-leo
Copy link
Author

I created a minimal working example

The problem only occurs when I ask nock to intercept http traffic and if I then use a Rule. It does not occur if I run the rule as a test. Thus I think there is a difference when running a rule instead of a test, which is causing the delay.

I tried using testcafe's Http mocking mechanism, but I couldn't get it to work and I found it harder to debug than nock, which offers logging out of the box.

@need-response-app need-response-app bot added the STATE: Need response An issue that requires a response or attention from the team. label Feb 20, 2019
@no-response no-response bot removed the STATE: Need clarification An issue lacks information for further research. label Feb 20, 2019
@Farfurix Farfurix self-assigned this Feb 20, 2019
@Farfurix
Copy link
Contributor

Farfurix commented Feb 20, 2019

Hello, @inctec-leo.

Thank you for providing additional information. I reproduced this issue on Windows 10, but I didn't reproduce it on another machine. I'm not sure if the issue is related to the Role mechanism. While we are working on it, you can use the following workaround:

import { Role, RequestMock } from 'testcafe';

const authUserRole = Role('http://localhost:8080/login', async t => {
    await t.typeText('#login-email', 'email');
    await t.typeText('#login-password', 'password');
});

const mock = RequestMock()
    .onRequestTo('/story/stories')
    .respond('test', 200);

fixture(`Main Page`)
    .page('http://localhost:8080/');

test
    .requestHooks(mock)
    ('When logged in the user sees the list of stories', async t => {
        await t.useRole(authUserRole);
        // ...
});

@need-response-app need-response-app bot removed the STATE: Need response An issue that requires a response or attention from the team. label Feb 20, 2019
@inctec-leo
Copy link
Author

inctec-leo commented Feb 20, 2019

Hi @Farfurix,
thanks for looking into this.
I can confirm that the behavior is very different on different machines.
My guess that this has something to do with the role mechanism is solely based on the behavior if the exact same code is being run in the test itself as in

 fixture(`Login Page`)
    .page('http://localhost:8080/login');

test('The user sends correct login information and is being logged in', async t => {
    nock('http://localhost:8080')
        .post('/auth/login')
        .reply(200, { "token": "testtoken" });
    await t.typeText('#login-email', 'email');
    await t.typeText('#login-password', 'password');

});

then there is no delay at all.

Edit: The proposed workaround does fix the delay, but it has no effect - http requests are not being mocked when using RequestMock.

@need-response-app need-response-app bot added STATE: Need response An issue that requires a response or attention from the team. and removed STATE: Need response An issue that requires a response or attention from the team. labels Feb 20, 2019
@Farfurix Farfurix added the STATE: Need response An issue that requires a response or attention from the team. label Feb 20, 2019
@Farfurix
Copy link
Contributor

@inctec-leo.

"http requests are not being mocked when using RequestMock".
I prepared a simple example and it's passed as expected. In the example below, I attached RequestMock to test:  

import { RequestMock } from "testcafe";

fixture `My Fixture`
    .page `https://google.com`;

const mock = RequestMock()
    .onRequestTo('https://google.com')
    .respond('test', 200);

test
    .requestHooks(mock)
    ('test', async (t) => {
    await t
        .wait(1000);
});

Could you please try to use RequestMock as shown above?

Also I tested your test scenario with only nock mocking and got the delay and unstable behavior. We need some additional time to investigate your case.

@need-response-app need-response-app bot removed the STATE: Need response An issue that requires a response or attention from the team. label Feb 22, 2019
@inctec-leo
Copy link
Author

@Farfurix

Is there any update on this? I would really like to use testcafe with nock. The issue with RequestMock seems to be that I can't figure out why it's not matching my routes (the routes are being matched when using nock), however there are other reasons why I would prefer nock.

Thanks.

@need-response-app need-response-app bot added the STATE: Need response An issue that requires a response or attention from the team. label Mar 11, 2019
@AlexKamaev AlexKamaev assigned AlexKamaev and unassigned Farfurix Mar 12, 2019
@AlexKamaev
Copy link
Contributor

@inctec-leo
I checked your example and found that the issue can be reproduced without roles. The cause of the issue is in the navigateTo function (the Roles mechanism uses it internally)

Here is an example:

test('test', async t => {
    var t0 = performance.now();

    nock('http://localhost:8080')
        .get('/story/stories')
        .reply(() => {
        });

    await t.debug();
    var t1 = performance.now();
    await t.navigateTo('http://localhost:8080');
    var t2 = performance.now();
    console.log("Navigate " + (t2 - t1) + " milliseconds.")
    await t.debug();
});

It looks like the nock somehow interferes the TestCafe working flow. I'll mark it as a bug for further research. However, since the behavior is very unclear I cannot give any estimation.

For the team:
With the nock, the waitForFileDownload command is executed for some reason.

@need-response-app need-response-app bot removed the STATE: Need response An issue that requires a response or attention from the team. label Mar 12, 2019
@AlexKamaev AlexKamaev added TYPE: bug The described behavior is considered as wrong (bug). and removed STATE: Need research labels Mar 12, 2019
@AlexKamaev AlexKamaev added this to the Planned milestone Mar 12, 2019
@AndreyBelym AndreyBelym removed the TYPE: bug The described behavior is considered as wrong (bug). label Mar 13, 2019
@AndreyBelym
Copy link
Contributor

It's not a bug, it's the way nock works by design. You can use nock.persist(), nock.restore() or nock(url, { allowUnmocked: true }) to get your code working.

There are a number of caveats when you use nock:

  1. By default, nock intercepts any request to the mocked endpoint and terminates it with an error if it can't find a corresponding response mock. Due to A proxied request hangs if a request to the original site emits an error testcafe-hammerhead#1961, failed requests are silently ignored. When we fix it, TestCafe will throw an error, so it won't make the situation better for you.
    If you pass the allowUnmocked: true flag when setting up nock, all requests that don't have corresponding mocks will be redirected to the real server, and it will make your code work.

  2. By default, a response mock expires when nock uses it for a request. All subsequent requests that can match an expired mock will throw an error as if no response mock is configured. You can use nock.persist to prevent mocks from expiring, or nock.restore() to completely disable nock after all required response mocks were applied.

@inctec-leo
Copy link
Author

@AndreyBelym

That makes sense and fixes the issue, thanks for looking into this.

@need-response-app need-response-app bot added the STATE: Need response An issue that requires a response or attention from the team. label Mar 15, 2019
@LavrovArtem LavrovArtem removed the STATE: Need response An issue that requires a response or attention from the team. label Mar 18, 2019
@AndreyBelym
Copy link
Contributor

Thank you for using TestCafe 😄

I lock this issue since the question is resolved. If you want to ask a new question - please create it on Stack Overflow. Also, don't hesitate to submit a new bug report or suggest an enhancement.

@DevExpress DevExpress locked as resolved and limited conversation to collaborators Mar 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants