sirkitree / angular-directive.g-signin

:triangular_ruler: AngularJS Directive for Google Plus Sign-in Button
http://jeradbitner.com/angular-directive.g-signin/
148 stars 84 forks source link

e2e protractor Test for the directive #16

Open DanielaValero opened 10 years ago

DanielaValero commented 10 years ago

Hi, I am using this directive, pretty cool! This is the code I am using with protractor to test it (In our case, we are using the force approval prompt)


    describe('Google+ auth', function () {

        var  util = require('util'),
        driver = browser.driver,
        handlePromise, popUpHandle, handle, originalHandle,
        button =  element(by.xpath('//button[contains(@style,"opacity")]'));

        beforeEach(function () {
            //Need to sleep, so the button can be rendered
            browser.sleep(2000);
            button.click();
            handlePromise = browser.getAllWindowHandles();
            browser.sleep(2000);
            var handles = handlePromise.then(function (handles) {
                popUpHandle = handles[1];
                originalHandle = handles[0];
                browser.switchTo().window(popUpHandle);
                handle = browser.getWindowHandle();
                expect(handle).toEqual(popUpHandle);
                browser.driver.executeScript('window.focus();');
            });

        });

        it('If user approval, should login the user', function () {
            element(by.id('Email')).sendKeys('foo@bar.com');
            element(by.id('Passwd')).sendKeys('foobarpassword');
            element(by.id('signIn')).click();
            browser.sleep(3000);
            element(by.id('submit_approve_access')).click(); //submit_deny_access
            browser.switchTo().window(originalHandle);
            browser.waitForAngular();
            expect(browser.getCurrentUrl()).toBe(browser.baseUrl + 'success-url');
        });

        it('If user disapproval, should remain in login page', function () {
            // --cancel button id:  submit_deny_access
            expect(url).toBe(browser.baseUrl + '/login');            
        });

       it('If window closed without approval, should remain in login page', function () {

        });
});
sirkitree commented 10 years ago

Interesting. Thank you for sharing. I've not done a lot of research into protractor. Do you know of any sort of best practice for including protractor tests with a module?

DanielaValero commented 10 years ago

I am not sure if I understand your question. But I've been diving into protractor the last days and it's been more complex than karma e2e, but it more powerful. Angular is now recommending it to be used in the e2e tests. There is no yet enough documentation over protractor, at least that is my impression. Most of the issues I've got, I've had them solved by browsing the issues of the repo, so I don't think there are official best practices.

About the test, I did some modifications in order to have the second (the one where the user doesnt allow access), but I'm getting an error I am not sure I understand yet.

describe('Google+ auth', function () {
        var  button, handlePromise, popUpHandle;

        //originalHandle = browser.getWindowHandle();
        beforeEach(function () {
            //Need to sleep, so the button can be rendered
            browser.sleep(2000);
            element(by.xpath('//button[contains(@style,"opacity")]')).click();
            handlePromise = browser.getAllWindowHandles();

            browser.sleep(1000);

            var handles = handlePromise.then(function (handles) {
                popUpHandle = handles[1];
                browser.switchTo().window(popUpHandle);
                expect(browser.getWindowHandle()).toEqual(popUpHandle);
                browser.driver.executeScript('window.focus();');
            });

            element(by.id('Email')).sendKeys('foo@bar.com');
            element(by.id('Passwd')).sendKeys('foobarpwd');
            element(by.id('signIn')).click();
        });

        it('If user approval, should login the user (if ran in localhost should fail)', function () {
            element(by.id('submit_approve_access')).click();
            browser.switchTo().window(originalHandle);
            expect(browser.getWindowHandle()).toEqual(originalHandle);
            browser.driver.executeScript('window.focus();');
            expect(browser.getCurrentUrl()).toBe(browser.baseUrl + '/');
        });

        it('If user disaproval, should remain in login page', function () {
            element(by.id('submit_deny_access')).click();
            browser.switchTo().window(originalHandle);
            expect(browser.getWindowHandle()).toEqual(originalHandle);
            browser.driver.executeScript('window.focus();');
            expect(browser.getCurrentUrl()).toBe(browser.baseUrl + 'app/login');

        });
    });

The error is:

UnknownError: unknown error: Element is not clickable at point (472, 479). Other element would receive the click: <button style="opacity: 0; z-index: 10000; left: 0px; top: 0px; position: absolute; cursor: pointer; outline: 0px; width: 164px; height: 47px;">...</button> The issue is that it doesn't seem to find the proper button, so it throws an error. Maybe it happens just in my scenario because I am using: browser.ignoreSynchronization = true; since I've got an issue with the $timeouts I couldn't resolve yet.

But anyway, sharing code makes the code better :)

sirkitree commented 10 years ago

Yes, thank you for sharing :smile:

My original questions is regarding the idea of including this with the module. Since this is a module, it's typically better to ship it with a unit test vs and end to end test. I think that end to end testing is more for use with an entire website. So this test would seem relevant in the context of your own website in which you're incorporating this module, but might not be for other websites.

For example, other sites may not even have an app/login path which would make the expect fail.

As such, karma tests (which are more unit based vs E2E) are typically what is shipped with a module (I think). I'd be happy to be proven wrong since we have no tests at all that ship with this module currently. But thus far I'm thinking that this is not something that we'd probably incorporate into this code base unless it were somehow shipped as an example E2E test or something of that nature.

DanielaValero commented 10 years ago

I understand now. Tests can be added to modules ie : angular-ui select2, in this case, the angular-ui developers run the tests in the project in development mode, and the app/website developers include just the js file containing the module in their site.

So, in this case, could be done something similar, or not, either tests can be included in the module to be tested in development mode, or the app/website developers include the tests on their app/website.

In my opinion, could be more useful the later one, since in the g+ authentication with js, we need to send the resulting data - after the user approval - to the server, so it signs in the user. In my case, wanted to know if this is going ok.

There are other scenarios, where the developer prefers not to force the approval prompt, for example. In such case, this test wouldn't work.