Testcafe Authentication issues - authentication

I have a Fixture which includes 2 Tests. Both tests accessing the same site with httpAuth().
The first request loads the page correctly and everything is ok. But the second test can't even load the page completely. A lot of requests are stuck on "Pending". On the IIS and also on our Proxy i see that every Request from Testcafe-Hammerhead is logged twice first with an 401 without credentials and then 200 with credentials. But when checking the log for the Second test for some request i only see the 401 Request without credentials.
After some minutes the test stops because of timeouts.
Here is a sample of the Test:
fixture("Getting Started").page(pageUrl).httpAuth(devAuth);
test("Test 1", async t => {
await t.maximizeWindow();
await t.debug();
var text = Selector("#content").find("h1");
var headerText = await text.innerText;
console.log("Found text: " +headerText);
await t.expect(headerText).eql("About our Team");
});
test("Test 2", async t => {
await t.maximizeWindow();
await t.debug();
var text = Selector("#content").find("h1");
var headerText = await text.innerText;
console.log("Found text: " +headerText);
await t.expect(headerText).eql("About our Team");
});

We found out that Testcafe opens for every request a new connection on our Proxy. This used all available connections and no new connections could be made which results that some requests are stuck in "Pending". That every request opens a new Connection on our Proxy is only via Testcafe. We will further investigate this.

Related

How do I check network response in playwright?

I want to test the network https status response with playwright.
test.only('Rights.2: Users without the required author role do not have access.', async ({page}) => {
await login(page, 'xxx', "password.xxx");
const search = await searchForProcess(page, `${process.process1.title}`);
await login(page, 'PortalUser');
const open = await openProcess(page, `${process.process1.title}`);
});
So I tried with this
expect(response.status()).toEqual(403);
But it won't work, because response is not defined. Thats curious, because Playwright does document the "response.status()" as a function.
Can somebody help?
You could try page.waitForResponse(). Official docs:
https://playwright.dev/docs/api/class-page#page-wait-for-response
Here is an example where we click a button and we want to monitor that certain API calls actually happen and that they have certain response statuses:
// Start waiting for all required API calls as we select company.
// We can accept only 200 but we could accept 403 like with /api/Environment/
await Promise.all([
page.waitForResponse(resp => resp.url().includes('/api/Environment/') && (resp.status() === 200 || resp.status() === 403)),
page.waitForResponse(resp => resp.url().includes('/api/Security/') && (resp.status() === 200)),
// We already started waiting before we perform the click that triggers the API calls. So now we just perform the click
page.locator('div[role="gridcell"]:has-text("text")').click()
]);
If you wish to validate other reponse data, see: https://playwright.dev/docs/api/class-response
If you want to monitor all network traffic, this official docs would be more suitable: https://playwright.dev/docs/network#network-events

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

Where do you place NPM's request code?

I want to use the request module in my express app, but I am not sure where the actual requests code goes.
Usage:
When a user loads a page, make a GET request and populate the page with data.
When a users clicks on a item from a table, make a GET request.
When a user fills out a form, POST.
I tried searching for answers but it seems to be implied that the developer knows where to place the code.
Example of a code snippet using request that I am unsure where to place in the express app:
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Show the HTML for the Google homepage.
}
})
I am guessing that I should not place the code in the server.js file especially if I am going to be making many different calls, but that's what it looks like others are doing on StackOverflow.
Does the request belong in a model?
If you are doing this in response to a user interaction, like clicking on something you can just do it from the route handler. Below, I just return the results to the client, or I pass an error to the next handler in the chain.
var request = require('request');
var express = require('express');
var app = express();
app.get('/click', function(req, res, next){
request('http://www.google.com', function (error, response, body) {
if (error || response.statusCode != 200)
return next(err);
response.send(body) // return the html to the client
})
});
app.listen(3000);
In bigger apps you might move routes into separate modules.

What should I consider when I am doing an authentication process with a titanium app?

Hello it's my first time doing a sign in process in a mobile app with Titanium and I wonder what information should I save and the best practice to do it?
My server is configured in this way:
The server requires I send a user and password and if the information match it will provide a token session.
This is the code I use for signing in:
function signIn(e) {
//function to use HTTP to connect to a web server and transfer the data.
var sendit = Ti.Network.createHTTPClient({
onerror : function(e) {
Ti.API.debug(e.error);
alert('There was an error during the connection');
},
timeout : 100000,
});
//Here you have to change it for your local ip
sendit.open('POST', 'http://myserver');
var params = {
user : $.txtUsuario.value,
password : $.txtPassword.value
};
sendit.send(params);
//Function to be called upon a successful response
sendit.onload = function() {
var json = this.responseText;
var response = JSON.parse(json);
if (response.success == "true")
{
var landing = Alloy.createController("menu").getView();
$.index.close();
landing.open();
}
else
{
alert(response);
}
};
};
the code above is working, however I do not know how to manage the sign out. I would like my application works like the most apps do, e.g:
You sign in once and after that if you do not close the app you are able to continues using it and even making a request.
Thank you for any explanation.
It depends on your app requirements. for exemple if you will use the token in your app later you can save it as an AppProperty :
Ti.App.Properties.setString('token',yourTokenGoHere);
and in the app starting you can get it back :
var myToken = Ti.App.Properties.getString('token');
and then you can make a test for example if the token is still valid or not :
if(myToken === 'invalidtoken')
youSholdLogin();
else
youCanGoFurther();
and when the user disconnect rest the token to be invalid :
Ti.App.Properties.setString('token', 'invalidtoken');

Backbone.js and user authentication

I have been wondering for quite a while how I would go about authenticating users using Backbone because I have been reading a few articles about it and a lot of them are talking about tokens and keys.. But I just want to be able to sign in a user and register a user like you would normally.
I was thinking that on the web app start up there would be a request to the route '/me' and then the server gives the user back appropriate information if he/she is logged in.
Like if the route came back with {loggedIn: false} the backbone router would send the user to the login/register pages only. But if it came back with a users profile information then it would obviously mean he had a session.
Is this an okay way of going back user authentication when using Backbone?
Short answer: wire up $.ajax to respond to 401 (Unauthorized) status codes.
Long answer: We're consuming a RESTful api from a single page website. when the server detects an unauthorized request, it just returns a 401. The client will redirect to /login?#requested/resource.
/login will prompt for authorization (redirect to google's oath server in our case) then add an authorization cookie and redirect to the originally requested #requested/resource
we're also sending the auth cookie on every $.ajax request.
Hopefully this is helpful.
define(
[
'jquery',
'jquery.cookie'
],
function ($) {
var redirectToLogin = function () {
var locationhref = "/login";
if (location.hash && location.hash.length > 0) {
locationhref += "?hash=" + location.hash.substring(1);
}
location.href = locationhref;
};
var $doc = $(document);
$doc.ajaxSend(function (event, xhr) {
var authToken = $.cookie('access_token');
if (authToken) {
xhr.setRequestHeader("Authorization", "Bearer " + authToken);
}
});
$doc.ajaxError(function (event, xhr) {
if (xhr.status == 401)
redirectToLogin();
});
});