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

Support of the new window simulation into iframe for the login via social networks purposes #1428

Closed
LavrovArtem opened this issue Dec 20, 2017 · 27 comments
Assignees
Labels
STATE: Auto-locked Issues that were automatically locked by the Lock bot TYPE: proposal

Comments

@LavrovArtem
Copy link
Contributor

LavrovArtem commented Dec 20, 2017

I've figured out that we have simple way to login via social networks. I've tried to log in to the site from an issue #1385 via a Facebook account and I've got it in two steps:

const patchAuth = ClientFunction(() => {
    window.open = function (url) {
        var iframe = document.createElement('iframe');

        iframe.style.position = 'fixed';
        iframe.style.left = '200px';
        iframe.style.top = '150px';
        iframe.style.width = '400px';
        iframe.style.height = '300px';
        iframe.style['z-index'] = '99999999';;		
        iframe.src = url;
        iframe.id = 'auth-iframe';

        document.body.appendChild(iframe);
    };
});

Final test:

fixture `fixture`
    .page `https://www.soudfa.com/signup`;

test('test', async t => {
    await patchAuth();

    await t
        .click('button.facebook')
        .switchToIframe('#auth-iframe')
        .typeText('#email', 'email***')
        .typeText('#pass', 'pass***')
        .click('#u_0_0')
        .wait(30e3);
});
@neilmatillano
Copy link

neilmatillano commented Dec 21, 2017

@LavrovArtem

Tried this proposal but I am blocked with few errors:

const patchAuth = new ClientFunction(() => {
Error: TypeScript compilation failed.
Only a void function can be called with the 'new' keyword.

Note that I already have this : import { Selector, Role, ClientFunction } from "testcafe"
So I removed the "new' keyword but I still get the error below.

For this line -- window.open = function (url) {
Error: TypeScript compilation failed.
/Users/admin/ark-e2e/tests/testCampaign_flow.ts (41, 9): Type '(url: string) => void' is not assignable to type '(url?: string, target?: string, features?: string, replace?: boolean) => Window'.
Type 'void' is not assignable to type 'Window'.

@LavrovArtem
Copy link
Contributor Author

LavrovArtem commented Dec 22, 2017

Hi @neilmatillano,
Fixed type script test:

import { ClientFunction } from 'testcafe';

const patchAuth = ClientFunction(() => {
    window['op' + 'en'] = function (url) {
        var iframe = document.createElement('iframe');

        iframe.style.position = 'fixed';
        iframe.style.left = '200px';
        iframe.style.top = '150px';
        iframe.style.width = '400px';
        iframe.style.height = '300px';
        iframe.style['z-index'] = '99999999';;		
        iframe.src = url;
        iframe.id = 'auth-iframe';
		
        document.body.appendChild(iframe);
    };
});

fixture `fixture`
    .page `your site`
	
test('test', async t => {
    await patchAuth();

    await t
        .click('.btn.btn-big.btn-fb')
        .switchToIframe('#auth-iframe')
        .typeText('#email', 'email***')
        .typeText('#pass', 'pass***')
        .click('#u_0_0')
        .wait(30e3);
});

But you also should find the testcafe-hammerhead/lib/request-pipeline/header-transforms.js file in the node_modules folder and replace current function of the x-frame-options property to the skip function ('x-frame-options': skip,).

@neilmatillano
Copy link

neilmatillano commented Dec 22, 2017

@LavrovArtem

I followed all the steps including updating the transforms js, but I am getting this error when running testcafe locally regarding the #auth-iframe

  1. The specified selector does not match any element in the DOM tree.

    Browser: Chrome 63.0.3239 / Mac OS X 10.13.2

      65 |    const loginBtn = Selector("input[name=\"login\"]")
      66 |    const signupBtn = Selector(elementWithIdOrClassName("btn btn-big btn-main-color"))
      67 |
      68 |    await testController
      69 |        .click(loginSelector)
    > 70 |        .switchToIframe('#auth-iframe')
    

@LavrovArtem
Copy link
Contributor Author

LavrovArtem commented Dec 22, 2017

@neilmatillano
Maybe you lost a call of the patchAuth function.

test('test', async t => {
    await patchAuth();  // <<<<<<<<< this

    await t
        .click('.btn.btn-big.btn-fb')
        .switchToIframe('#auth-iframe')
        .typeText('#email', 'email***')
        .typeText('#pass', 'pass***')
        .click('#u_0_0')
        .wait(30e3);
});

@neilmatillano
Copy link

neilmatillano commented Dec 22, 2017

@LavrovArtem yeah i forgot, added now but get another error.
Sorry this is a bit hard to debug on my side... I cant get any more info

Request failed with status code 500

  Browser: Chrome 63.0.3239 / Mac OS X 10.13.2

     68 |    const signupBtn = Selector(elementWithIdOrClassName("btn btn-big btn-main-color"))
     69 |
     70 |
     71 |    await testController
     72 |        .click(loginSelector)
   > 73 |        .switchToIframe('#auth-iframe')

I also get these errors:

Failed to load resource: the server responded with a status of 400 (Bad Request)
hammerhead.js:2 Error while refreshing the token: Error: Request failed with status code 400
at createError (app.js?88d6c1acb5583bded9d1:17375)
at settle (app.js?88d6c1acb5583bded9d1:4833)
at XMLHttpRequest.handleLoad (app.js?88d6c1acb5583bded9d1:9789)
window.console.(anonymous function) @ hammerhead.js:2
:49196/BJCTWA9fG/http://localhost:8080/api/translations/keys Failed to load resource: the server responded with a status of 500 (Internal Server Error)

@LavrovArtem
Copy link
Contributor Author

LavrovArtem commented Dec 25, 2017

Hi @neilmatillano,
The 500 failed code maybe related with x-frame-options replacement. Be convinced that you correctly replaced function in /node_modules/testcafe/node_modules/testcafe-hammerhead/lib/request-pipeline/header-transforms.js.

@neilmatillano
Copy link

@LavrovArtem , is there anyway to remember in the browser the login for facebook that I previously did so I don't need to login again when I run testcafe? I tried using chrome:userProfile but it didnt help.

@LavrovArtem
Copy link
Contributor Author

Hi @neilmatillano,
The User Roles feature should meet your need.

@neilmatillano
Copy link

@LavrovArtem , yes I tried this one but the problem is I still get redirected to the login page even after I saved the login.

@neilmatillano
Copy link

Or how about session cookies, is it supported in testcafe?

@LavrovArtem
Copy link
Contributor Author

I've created example with User Roles for you:

import { ClientFunction, Role, Selector } from 'testcafe';

const patchAuth = ClientFunction(() => {
    window['op' + 'en'] = function (url) {
        var iframe = document.createElement('iframe');

        iframe.style.position = 'fixed';
        iframe.style.left = '200px';
        iframe.style.top = '150px';
        iframe.style.width = '400px';
        iframe.style.height = '300px';
        iframe.style['z-index'] = '99999999';;		
        iframe.src = url;
        iframe.id = 'auth-iframe';

        document.body.appendChild(iframe);
    };
});

const facebookAccUser = Role('<your site url>/login', async t => {
    await patchAuth();

    await t
        .click('.btn.btn-big.btn-fb')
        .switchToIframe('#auth-iframe')
        .typeText('#email', 'email')
        .typeText('#pass', 'pass')
        .click('#u_0_0')
        .switchToMainWindow();

    await Selector('#page-header-top-menu')();
});

fixture `fixture`
    .page `<your site url>`
    .beforeEach(async t => await t.useRole(facebookAccUser));
	
test('first test', async t => {
    await t.click(Selector('.dashboard-tab').nth(1));
});

test('second test', async t => {
    await t.click(Selector('.dashboard-tab').nth(2));
});

@neilmatillano
Copy link

neilmatillano commented Dec 26, 2017

@LavrovArtem , I'm sorry but I am getting an error with the example but I do appreciate your help in giving me the example.

    • Error in Role initializer -
      Error on page "http://localhost:8080/login":

      Uncaught TypeError: Cannot read property 'call' of undefined

      Browser: Chrome 63.0.3239 / Mac OS X 10.13.2

      24 |const facebookAccUser = Role('http://localhost:8080/login',
      

      async t => {
      25 | await patchAuth();
      26 |
      27 | await t

      28 | .click('.btn.btn-big.btn-fb')
      29 | .switchToIframe('#auth-iframe')
      30 | .typeText('#email', 'email')
      31 | .typeText('#pass', 'pass')
      32 | .click('#u_0_0')
      33 | .switchToMainWindow();

And I checked the fb login is present.

And also just to be clear, in header-transforms.js, I have this skipped option,

'x-frame-options': skip,
  /* function xFrameOptions(src, ctx) {
    if (src.indexOf('ALLOW-FROM') === -1) return src;

    src = src.replace('ALLOW-FROM', '').trim();

    var isCrossDomain = ctx.isIframe && !urlUtils.sameOriginCheck(ctx.dest.url, src);
    var proxiedUrl = ctx.toProxyUrl(src, isCrossDomain, ctx.contentInfo.contentTypeUrlToken);

    return 'ALLOW-FROM ' + proxiedUrl;
}, */

@LavrovArtem
Copy link
Contributor Author

LavrovArtem commented Dec 27, 2017

Hi @neilmatillano,
This error occurs on your site and TestCafe detects it. Please try to run TestCafe with the --skip-js-errors flag. (more information):

@viking2917
Copy link

@LavrovArtem Thanks for this example. I am also trying to use Test Cafe to test my app with Facebook login (I am using Ionic and the Facebook login plugin as well)

When I follow your steps above, I get the following errors:

O {code: "auth/popup-blocked", message: "Unable to establish a connection with the popup. It may have been blocked by the browser."} "email: " undefined "code " "auth/popup-blocked" (from hammerhead.js line 2)

and

Refused to display 'http://192.168.1.82:54306/2Bt1Drjkn!i/https://m.facebook.com/login.php?skip_api_login=1&api_key=518797921496187&signed_next=1&next=https%3A%2F%2Fm.facebook.com%2Fv2.8%2Fdialog%2Foauth%3Fredirect_uri%3D.......' in a frame because it set 'X-Frame-Options' to 'deny'.

I think this is because the url of the frame opening the FB login is 'http://192.168.1.82:54306/ ...' and my Facebook Login settings do not include that particular URL/port combination in the 'Valid OAuth redirect URIs' settings. But because test cafe generates a new port number every time, I don't see any way to add it...not sure if that's clear but wondering if you have any suggestions?

Thanks!

@LavrovArtem
Copy link
Contributor Author

Hi @viking2917,
The Refused to display error maybe related with x-frame-options replacement.

#1428 (comment)
#1428 (comment)

I will add PR which rid you from a node_modules code modification, as soon as possible.

@viking2917
Copy link

Thanks @LavrovArtem I did modify the header-transforms.js to make the change to 'x-frame-options': skip, but it's possible I messed up somewhere along the way...

@joshpitzalis
Copy link

I am getting the same popup-blocked error

M {code: "auth/popup-blocked", message: "Unable to establish a connection with the popup. It may have been blocked by the browser."}

I have made sure that I skipped the x-frame-options in header-transfor.js:

screen shot 2018-06-14 at 11 57 42 am

tried jumping into chrome setting and allowing popups before the login button get clicked but no difference. Has anyone found a way around this yet?

@LavrovArtem
Copy link
Contributor Author

Hi @joshpitzalis,
I need some time to investigate it.

@MohamedRasool786
Copy link

@LavrovArtem

I have faced issue while clicking on a #googleSignInn button. It doesn't redirect to the google POPUP page.Below I attached my code

Expected Behaviour is to give my credentials in google popup page and then it should redirect to my homesite.

Thanks in advance

`import { ClientFunction, Role, Selector } from 'testcafe';

const patchAuth = ClientFunction(() => {
window['op' + 'en'] = function (url) {
var iframe = document.createElement('iframe');

iframe.style.position = 'fixed';
iframe.style.left = '100px';
iframe.style.top = '150px';
iframe.style.width = '600px';
iframe.style.height = '600px';
iframe.style['z-index'] = '99999999';;		
iframe.src = url;
iframe.id = 'auth-iframe';

document.body.appendChild(iframe);

};
});

const googleAccUser = Role('https://merida-web.herokuapp.com/', async t => {
await patchAuth();

await t
.click("#LoggIn")
.click("#googleSignInn")
.switchToIframe('#auth-iframe')
.typeText('#identifierId', '[email protected]')
.click("#identifierNext")
.typeText('#password', 'maduraiboys007')
.click("#passwordNext")
.switchToMainWindow();

await Selector('#page-header-top-menu')();
});

fixture Merida E2E Testing
.page https://merida-web.herokuapp.com/
.beforeEach(async t => await t.useRole(googleAccUser));

test('first test', async t => {
await t.click(Selector('.dashboard-tab').nth(2));
});`

@LavrovArtem
Copy link
Contributor Author

Hi @joshpitzalis,
There are two header-transforms.js files which should be modified.
image

@LavrovArtem
Copy link
Contributor Author

Hi @MohamedRasool786,
I will investigate it.

@MohamedRasool786
Copy link

Hi @LavrovArtem

Thanks for your cool reply!
I have tried that too, It's not working to me, Am using firebase google authentication for log in.

Is it possible to do for firebase google authentication in Testcafe.

@LavrovArtem
Copy link
Contributor Author

@MohamedRasool786
Unfortunately, I cannot find a workaround for google authentication.

@MohamedRasool786
Copy link

@LavrovArtem
Thanks.
Is it possible to do using iFrames as like Facebook you did before in #1385

@LavrovArtem
Copy link
Contributor Author

LavrovArtem commented Jun 25, 2018

@MohamedRasool786
I just tried to use the same iframe workaround as for Facebook but Google authentication is more difficult.

@miherlosev
Copy link
Contributor

We are developing a public API for operating with multiple windows simultaneously. Track DevExpress/testcafe#912 to be informed about our progress.

@lock
Copy link

lock bot commented Feb 23, 2020

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 Issues that were automatically locked by the Lock bot label Feb 23, 2020
@lock lock bot locked as resolved and limited conversation to collaborators Feb 23, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
STATE: Auto-locked Issues that were automatically locked by the Lock bot TYPE: proposal
Projects
None yet
Development

No branches or pull requests

6 participants