Ember-auth signin test fails with json - testing

I am having some issues with testing my signin/signout and related features of my app. The app works, but the test fail.
For testing, I use a QUnit with testem (I also tried teaspoon)
test "after signin, should redirect user back to previous page", ->
visit '/library'
fillIn '.signin-email', 'example#example.com'
fillIn '.signin-password', 'examplepass'
click '.signin-btn'
andThen ->
equal(testing().path(), 'library', "Should redirect back to library (was #{testing().path()})")
After running the test, I get a failure:
(screenshot here )
Authentication: visiting restricted page as non authenticated user: after signin, should redirect user back to previous page (2, 0, 2)Rerun544 ms
{user_id: 2, auth_token: wVveiyDLuXBXu69pQ2XQwg}
Source:
at Test.QUnitAdapter.Test.Adapter.extend.exception (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:50149:5)
at superWrapper [as exception] (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:13374:16)
at Object.onerror (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:50009:22)
at onerror (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20453:16)
at EventTarget.trigger (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20286:22)
at null.<anonymous> (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20439:14)
at EventTarget.trigger (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20286:22)
at http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20588:17
Should redirect back to library (was signin)
Expected:
"library"
Result:
"signin"
Diff:
"library" "signin"
Source:
at http://localhost:7357/public/assets/spec/javascripts/integration/authentication_pages_spec.js.js:22:14
at andThen (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:50258:20)
at http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:49817:21
at isolate (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:49989:14)
at http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:49972:12
at invokeCallback (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20463:19)
at null.<anonymous> (http://localhost:7357/public/assets/application-aad0a1b2c887cc25124c361787446e83.js:20513:11)
Also, auth.coffee:
App.Auth = Em.Auth.extend
request: 'jquery'
response: 'json'
strategy: 'token'
session: 'cookie'
modules: [
'emberData',
'authRedirectable',
'actionRedirectable'
]
signInEndPoint: '/signin'
signOutEndPoint: '/signout'
tokenKey: 'auth_token'
tokenIdKey: 'user_id'
tokenLocation: 'param'
emberData:
userModel: 'user' # create user model on login
authRedirectable:
route: 'signin'
actionRedirectable:
signInRoute: 'library'
# signInSmart: true
# signInBlacklist: ['signin']
signOutRoute: 'index'
I am unable to find the source of the error, so maybe it is something to do with ember-auth. Any ideas would be very appreciated.
Update 1 [Jan 4th]:
I've written an additional test, which passes only halfway. The test is simpler than the previous in that it does not check a redirect, but only checks that the user name appears in the UI after signin.
test "after signin, TEST", ->
visit '/library'
fillIn '.signin-email', 'user#example.com'
fillIn '.signin-password', 'foobargaz'
click '.signin-btn'
andThen ->
ok exists('.menu-signout'), "signout button exists"
The assertions passes, but I get an additional error reporting the returned JSON as seen in this screenshot. The screenshot basically shows:
[Fail] {user_id: 2, auth_token: wVveiyDLuXBXu69pQ2XQwg}
[Pass] signout button exists
Additionally, I've also run the tests by mocking the ajax requests with mockjax, but with the same failure.
Third, I should note that I had to patch "ember-auth-request-jquery.js" to make it work with ember testing as suggested here

I'm pretty sure you're failing to wait on the first visit to happen, so here's how I read it (I'm no CS person)
You're telling Ember to go to library
Before being sure it's finished navigating you're trying to fill in 2 fields and click a button (all of which probably doesn't exist)
then you check to see if it's library, but while waiting after you thought you clicked, really the page finishes rendering the login page from the visit
Here's what js2coffe says it'd kind of look like (my main point is the then after the visit).
test "after signin, should redirect user back to previous page", ->
visit("/library").then ->
fillIn ".signin-email", "example#example.com"
fillIn ".signin-password", "examplepass"
click(".signin-btn").then ->
equal testing().path(), "library", "Should redirect back to library (was " + (testing().path()) + ")"
Update 1/4: Documentation changed on me
Now we move to educated guess time. Looking through the Ember-auth code it might not be creating any timers/promises that Ember is aware of, in affect Ember thinks it's finished the signin process immediately. So the click promise is resolved immediately and you run your test immediately (andThen waits on the global testing promise to resolve). To test the theory you can do some terrible timeout and see if it does indeed redirect after some time
test "after signin, should redirect user back to previous page", ->
visit "/library"
fillIn ".signin-email", "example#example.com"
fillIn ".signin-password", "examplepass"
click ".signin-btn"
stop()
Ember.run.later this, (->
start()
equal testing().path(), "library", "Should redirect back to library (was " + (testing().path()) + ")"
), 5000

It turns out my coffeescript was not the best in the world.
The module function in QUnit should NOT compile to:
module('Authentication: visiting restricted page as non authenticated user', function() {
return setup(function() {
return Em.run(App, App.advanceReadiness);
});
});
but to:
module('Authentication: visiting restricted page as non authenticated user', {
setup: function() {
Ember.run(App, App.advanceReadiness);
},
// This is also new
teardown: function() {
App.reset();
}
});
Additionally, in my spec_helper.coffee file I had something like this:
QUnit.testStart(function() {
// FIXME: this below made it fail every time
// Ember.run(function() {
// return App.reset();
// });
Ember.testing = true;
});
QUnit.testDone(function() {
Ember.testing = false;
});
QUnit.done(function() {
return Ember.run(function() {
return App.reset();
});
});
which seems to have caused some issues, so I just deleted it and the tests now pass.

Related

How to login with HTTP basic authentication to ACCESS the website- Test Cafe with Gherkin and cucumber

All links, project name and company name has been modified and are not original.
We have a basic HTTP authentication popup that appears when we are accessing out test/staging environments.
I am wondering, how can I enter the login information into the popup login window or send an api request in advance to save the cookie?
Because otherwise, I can't run the automation on our test environment. When the test access the page, I see a white website showing "unauthorized" in small letters.
This is what the login prompt looks like when accessing the Test/Staging env
We are using following plugin: https://www.npmjs.com/package/gherkin-testcafe
What I am asking is very similar to this question: Testing http basic authentication with Cucumber and RSpec in Rails 3.2.3
I have tried adding a role and using TestCafe http-authentication.html
Here is what I have tested so far:
TestCafe trying to use role:
const { Role } = require('testcafe');
const regularAccUser = Role('https://website/login', async t => {
await t
.typeText('#login', 'username')
.typeText('#password', 'password')
.click('#sign-in');
});
Given("I am open Dealer's login page", async t => {
await t
.useRole(regularAccUser)
.navigateTo(`${url}/login`);
});
That gives me:
ERROR CompositeParserException: Parser errors:
(7:3): expected: #EOF, #Comment, #BackgroundLine, #TagLine, #ScenarioLine, #ScenarioOutlineLine, #Empty, got 'Correct action happens when user provide either wrong or correct login information'
at Function.Errors.CompositeParserException.create (/Users/dennis/Projects/src/company/project/node_modules/gherkin/lib/gherkin/errors.js:27:13)
at Parser.parse (/Users/dennis/Projects/src/company/project/node_modules/gherkin/lib/gherkin/parser.js:72:45)
at specFiles.forEach.specFile (/Users/dennis/Projects/src/company/project/node_modules/gherkin-testcafe/src/compiler.js:43:33)
at Array.forEach (<anonymous>)
at GherkinTestcafeCompiler.getTests (/Users/dennis/Projects/src/company/project/node_modules/gherkin-testcafe/src/compiler.js:42:20)
at getTests (/Users/dennis/Projects/src/company/project/node_modules/testcafe/src/runner/bootstrapper.js:79:47)
at Generator.next (<anonymous>)
at step (/Users/dennis/Projects/src/company/project/node_modules/babel-runtime/helpers/asyncToGenerator.js:17:30)
at /Users/dennis/Projects/src/company/project/node_modules/babel-runtime/helpers/asyncToGenerator.js:28:13
If I try using:
import {Role} from 'testcafe'
I get:
tests/ui/stepDefinitions/login/login.js:1
(function (exports, require, module, __filename, __dirname) { import { Role } from 'testcafe';
^
SyntaxError: Unexpected token {
Using TestCafe's HTTP Authentication:
Feature: Login with correct and wrong info functionallity
.page('website/login')
.httpAuth({
username: 'username',
password: 'password',
})
Correct action happens when user provide either wrong or correct login information
#loginFunc
Scenario: Should NOT be able to login without filling in any credentials
Given I am open Dealer's login page
When I am login in with "empty" and "empty"
Then I should NOT be able to press the login button
I am getting following:
Feature: Login with correct and wrong info functionallity
✖ Scenario: Should NOT be able to login without filling in any credentials
1) Cannot obtain information about the node because the specified selector does not match any node in the DOM tree.
  | Selector('button[data-qa="qa-login-submit-button"]')
 > | Selector('button[data-qa="qa-login-submit-button"]')
Browser: Chrome 72.0.3626 / Mac OS X 10.14.3
32 | }
33 |});
34 |
35 |Then("I should NOT be able to press the login button", async t => {
36 | await t
> 37 | .expect(submitButton.hasAttribute('disabled')).ok()
38 | .expect(h1.exists).eql(true);
39 |});
```
It is basically showing me a white screen and saying: "**unauthorized**" in small letters.
You don't need any post/get requests with the Basic HTTP. Instead, you can log in using the Role mechanism:
When you switch to a role for the first time, TestCafe internally creates a branch of this role for this particular test run. All cookies set by your further actions will be appended to this branch. This branch will be used whenever you switch back to this role from the same test run.

Not able to close the browser using NightwatchJS

I am trying to open my url using Nightwatch and I wan't able to close the browser afterwards.
I tried using timeouts, as well as browser.end(), or browser.closeWindow(). None of them seem to be working for my url.
module.exports = {
'Demo test mywrkouts' : function (browser) {
browser.url('https://www.mywrkouts.com/workouts/search')
browser.timeouts('script', 10000, function(result) {
browser.end();
console.log("Test result"+result);
});
//browser.closeWindow();
}
};
It opens the page, but doesn't close the browser. I am using Chrome browser with chromedriver. I am expecting to close the window, but it doesn't work.
Any advice is appreciated.
LE: Like I extensibly described below, you don't need to explicitly close the browser at the end of the test (via browser.end()) as the Nightwatch test-runner does that for you at the end of each feature-file.
But, if you need to do some teardown operations and then explicitly close the session, do it in an after (or afterEach) hook. Try the following snippet:
module.exports = {
before(browser) {
browser.maximizeWindow();
},
'My Wrkouts Test': (browser) => {
browser.url('https://www.mywrkouts.com/');
// Check if the website logo is visible:
browser.expect.element('#barbell-homepage-top-image-desktop img.app-bar-desktop-logo').to.be.visible;
// Check the articles heading text:
browser.expect.element('h3.blog-carousel-title.primary-blue-text.center').text.to.contain('Foundational Education Series');
},
after(browser, done) {
browser.end(() => {
console.info('*--*--*--*--*--*--*--*--*--*--*--*--*');
console.info('*-- Clossing session... Good bye! --*');
console.info('*--*--*--*--*--*--*--*--*--*--*--*--*');
done();
});
}
};
Anyways, I feel you are confusing the way NightwatchJS/WebdriverIO/Protractor (or any other Webdriver-based test solution) is handling a browser session.
First off, you need not worry about closing the active session. Nightwatch does it for you at the end of each test feature-file. Thus, running a suit of let's say three test suites (login.js, register.js, forgot_password.js) will sequentially spawn & close three different browser sessions.
Also, browser.closeWindow() is only used for closing a window instance (taking into account that you have multiple windows associated with the same browser session). It won't close your main window, unless you have switched to another window instance (which was previously opened during your test run).
If you use browser.end() in the middle of your test, then you basically kill the active session, nullifying the following logic from your feature-file:
INFO Request: DELETE /wd/hub/session/4a4bb4cb1b38409ee466b0fc8af78101
- data:
- headers: {"Content-Length":0,"Authorization":"Basic Z29wcm86YmM3MDk2MGYtZGE0Yy00OGUyLTk5MGMtMzA5MmNmZGJhZTMz"}
INFO Response 200 DELETE /wd/hub/session/4a4bb4cb1b38409ee466b0fc8af78101 (56ms) { sessionId: '4a4bb4cb1b38409ee466b0fc8af78101',
status: 0,
value: null }
LOG → Completed command end (57 ms)
Everything after will look like this:
INFO Response 404 POST /wd/hub/session/null/elements (11ms) { sessionId: 'null',
value:
{ error: 'invalid session id',
message: 'No active session with ID null',
stacktrace: '' },
status: 6 }
!Note: There is no support for doing what you are trying to do, nor is it a common use-case, thus the lack of support for it across
all of these testing solutions.
They say a picture is worth 1000 words, so let's me simply put it this way... what you are trying to do is synonymous with the following:

experiencing super slow tests with testcafe

I'm currently experimenting testcafe for the first time, I use the testdriven.io course as an example, and I'm facing really slow tests.
For instance testcafe e2e/login.test.js which is basically a register and a login takes sometimes 6min to pass, which I found insanely slow compared to the 15s the author has in his course.
import {Selector} from 'testcafe';
const randomstring = require('randomstring');
const username = randomstring.generate();
const email = `${username}#test.com`;
const TEST_URL = process.env.TEST_URL;
fixture('/login').page(`${TEST_URL}/login`);
test(`should display the sign-in form`, async (t) => {
await t
.navigateTo(`${TEST_URL}/login`)
.expect(Selector('H1').withText('Login').exists).ok()
.expect(Selector('form').exists).ok()
});
test(`should allow a user to sign in`, async (t) => {
// register user
await t
.navigateTo(`${TEST_URL}/register`)
.typeText('input[name="username"]', username)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', 'test')
.click(Selector('input[type="submit"]'))
// log a user out
await t
.click(Selector('a').withText('Log Out'))
// log a user in
await t
.navigateTo(`${TEST_URL}/login`)
.typeText('input[name="email"]', email)
.typeText('input[name="password"]', 'test')
.click(Selector('input[type="submit"]'))
// assert user is redirected to '/'
// assert '/' is displayed properly
const tableRow = Selector('td').withText(username).parent();
await t
.expect(Selector('H1').withText('All Users').exists).ok()
.expect(tableRow.child().withText(username).exists).ok()
.expect(tableRow.child().withText(email).exists).ok()
.expect(Selector('a').withText('User Status').exists).ok()
.expect(Selector('a').withText('Log Out').exists).ok()
.expect(Selector('a').withText('Register').exists).notOk()
.expect(Selector('a').withText('Log In').exists).notOk()
// log a user out
await t
.click(Selector('a').withText('Log Out'))
// assert '/logout' is displayed properly
await t
.expect(Selector('p').withText('You are now logged out').exists).ok()
.expect(Selector('a').withText('User Status').exists).notOk()
.expect(Selector('a').withText('Log Out').exists).notOk()
.expect(Selector('a').withText('Register').exists).ok()
.expect(Selector('a').withText('Log In').exists).ok()
});
I tried with Firefox, same deal, albeit much faster, 44s.
(project-tOIAx_A8) ➜ testdriven-app git:(master) ✗ testcafe 'chromium' e2e/login.test.js
Using locally installed version of TestCafe.
(node:16048) ExperimentalWarning: The fs.promises API is experimental
Running tests in:
- Chrome 67.0.3396 / Linux 0.0.0
/login
✓ should display the sign in form
✓ should allow a user to sign in
2 passed (6m 15s)
I wish I could provide more info, went to the dev tools, inspected the console without noticing any error message except this one sometimes:
hammerhead.js:7 WebSocket connection to 'ws://192.168.1.195:38039/4wxhbvTF7!w!http%3A%2F%2F172.18.0.5/http://172.18.0.5/sockjs-node/444/2kjm15kn/websocket' failed: Error during WebSocket handshake: Unexpected response code: 400
, the waterfall looks like slow, is there a way to give a log report of it to help understand what cases this slowness ?
edit: I put a .debug() at beginning and at the end of the tests and save a Performance profile inside Firefox if that helps
edit2: this is a performance profile in chromium if that helps

Basic authentication with Selenium in Internet Explorer 11

I read Basic authentication with Selenium in Internet Explorer 10
And I change my register key and when I use the user and pass in the url I don't see the basic authentication popup, but actually the page is not load. I see blank page!
I see my url in the IE but nothing happened - I see white page.
Must I change somethin in IE too?
It is not possible without some workarounds.
I also needed the same feature and previous SO answer confirms, that is it either impossible or possible with high probability of failure.
One thing I learned about Protrator is not to try to make too complicated stuff with it, or I'll have a bad time.
As for the feature- I ended up making Protractor to initiate Node.js task, which use request to make the authentication and provide back the data.
Taken straight from request module:
request.get('http://some.server.com/').auth('username', 'password', false);
// or
request.get('http://some.server.com/', {
'auth': {
'user': 'username',
'pass': 'password',
'sendImmediately': false
}
});
// or
request.get('http://some.server.com/').auth(null, null, true, 'bearerToken');
// or
request.get('http://some.server.com/', {
'auth': {
'bearer': 'bearerToken'
}
});

Authentication testing with Meteor

I'm writing meteor tests that require authentication, and having a series of problems.
This is my code:
MochaWeb?.testOnly ->
describe "Login", ->
describe "security", ->
it 'should take you to /login/ if you are not logged in', ->
Meteor.flush()
chai.assert.equal Router.current().url, '/login/'
it 'should allow logins and then take us to /', ->
Meteor.flush()
Accounts.createUser username: 'test', password: 'test'
Meteor.loginWithPassword 'test', 'test', (err) ->
console.log err
chai.expect(err).to.be undefined
chai.assert.equal Router.current().url, '/'
My tests pass, even though I get console messages such as Exception in delivering result of invoking 'login': TypeError: object is not a function
My console.log call gives me
{error: 403, reason: "User not found", details: undefined, message: "User not found [403]", errorType: "Meteor.Error"…}
on the console, and nothing on the velocity log window
My user doesn't authenticate as I'd expect. One cause could be that my app doesn't have the accounts-password package, because I don't want it (I just want google apps users to be able to login). However I want an easy way to handle authentication in meteor tests, as most of my tests involve authenticated users.
I'm not sure whether the assert equal would work or I'd have to set some sort of timeout to wait for the redirection. In this case it wouldn't be a problem, but do I have to nest every test method I have inside loginWithPassword? I'd find this a bit uncomfortable.
Any help and suggestions much appreciated!
Best,
Are you sure you have user already created? I think you should create it in your fixture.js.
MochaWeb.testOnly(function() {
describe("Client", function() {
describe("firstTest", function() {
// Meteor.users.remove({});
before(function(done) {
Accounts.createUser(currentUser, function(err, success) {
Meteor.loginWithPassword(currentUser, function(err) {
console.log("This works");
// done();
});
});
});
});
});
});
Here is the source file, in which I have implemented the same
https://github.com/trinisofttechnologies/mocha-test/blob/master/tests/mocha/client/client.coffee
and this is the repo where the code resides
https://github.com/trinisofttechnologies/mocha-test