basic authentication does not work for local testing with cypress - automated-tests

I am developing a web app that requires windows credential. To test it locally during developing, I decide to try cypress.io. However, I cannot make it work. I always got an 401-unauthorized error. Here are some codes that I have used for my testing. Thanks for your help.
method 1:
describe('My First Test', function() {
it('Visits the Kitchen Sink', function() {
cy.visit('http://localhost:8080/')
})
})
method 2:
describe('My First Test', function() {
it('test website loading', function() {
cy.visit('http://localhost:8080/',{
auth: {
username:'myusername',
password:'myassword'
}
})
})
})
method 3: overwrite command
Cypress.Commands.overwrite('visit', (orig, url, options) => {
options = options || {}
options.auth = {
username: 'username',
password: 'password',
}
return orig(url, options)
})

Related

How to test for access prohibited in Cypress?

How do I test that if I try to visit a page that I'm not authorised for I get a 403 response?
This is what I'm trying so far:
cy.visit('/sys-ops')
cy.location('pathname').should('eq', '/error/unauthorized')
You could use something like this
describe('showcase Cypress request', () => {
it('checks for 403', () => {
cy.request({
url: '/my-unauthorized-url',
followRedirect: false,
failOnStatusCode: false
}).then((resp) => {
expect(resp.status).to.eq(403)
})
})
})
Find more details here https://docs.cypress.io/api/commands/request#Request-a-page-while-disabling-auto-redirect

How to redirect to starting point after authorizing with auth0 in a Nextjs application using #auth0/nextjs-auth0

I'm currently using auth0 to authenticate users in a Next.js application.
I'm using the #auth0/nextjs-auth0 SDK and following along with the documentation.
However, I'm having trouble figuring out how to redirect users dynamically after login based on the page they accessed the login form from.
In the app I’m currently trying to build, users can log in from “/” which is the home page, and from the navbar element in “/browse”. However, after logging in, it always redirects back to “/”, while I would like to redirect users to “/browse” or "/browse/[id] if that is where they began the login process from.
I’ve tried using https://community.auth0.com/t/redirecting-to-another-page-other-than-using-nextjs-auth0/66920 as a guide but this method only allows me to redirect to a pre-defined route. I would like to know how I could make the redirect URL dynamic.
Thanks in advance!
Edit: I’ve managed to find a solution for now by digging in to the req object and setting the returnTo value to “referer”.
import { handleAuth, handleLogin } from '#auth0/nextjs-auth0';
const getLoginState = (req, loginOptions) => {
return {
returnTo: req.headers.referer
};
};
export default handleAuth({
async login(req, res) {
try {
await handleLogin(req, res, { getLoginState });
} catch (err) {
res.status(err.status ?? 500).end(err.message)
}
}
});
I’m not seeing any obvious problems so far but I’m not entirely sure if this method has any drawbacks, so I would appreciate any feedback.
How about this?
Step 1: Initialize Auth0 SDK
https://auth0.github.io/nextjs-auth0/modules/instance.html#initauth0
# /lib/auth0,js
import { initAuth0 } from "#auth0/nextjs-auth0";
export default initAuth0({
secret: process.env.SESSION_COOKIE_SECRET,
issuerBaseURL: process.env.NEXT_PUBLIC_AUTH0_DOMAIN,
baseURL: process.env.NEXT_PUBLIC_BASE_URL,
clientID: process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID,
clientSecret: process.env.AUTH0_CLIENT_SECRET,
routes: {
callback:
process.env.NEXT_PUBLIC_REDIRECT_URI ||
"http://localhost:3000/api/auth/callback",
postLogoutRedirect:
process.env.NEXT_PUBLIC_POST_LOGOUT_REDIRECT_URI ||
"http://localhost:3000",
},
authorizationParams: {
response_type: "code",
scope: process.env.NEXT_PUBLIC_AUTH0_SCOPE,
},
session: {
absoluteDuration: process.env.SESSION_COOKIE_LIFETIME,
},
});
Step 2: Configure Login
https://auth0.github.io/nextjs-auth0/modules/handlers_login.html#handlelogin
https://auth0.github.io/nextjs-auth0/interfaces/handlers_login.loginoptions.html#returnto
# /pages/api/auth/login.js
import auth0 from "../../../lib/auth0";
export default async function login(req, res) {
let options = {
returnTo: 'http://localhost:3000/dashboard'
}
try {
await auth0.handleLogin(req, res, options);
} catch (error) {
console.error(error);
res.status(error.status || 500).end(error.message);
}
}
Now you will land on the dashboard page after successfully authenticating.
Step 3: Helpful Sanity Check
create /pages/api/auth/callback.js with the following content
import auth0 from "../../../lib/auth0";
const afterCallback = (req, res, session, state) => {
// console.log(session)
console.log(state)
return session
};
export default async function callback(req, res) {
try {
console.log(auth0)
await auth0.handleCallback(req, res, { afterCallback });
} catch (error) {
console.error(error);
res.status(error.status || 500).end(error.message);
}
}
Try logging in and look for the state in the console,
{ returnTo: 'http://localhost:3000/dashboard' }
Cheers!

Meteor HTTP.POST call on same machine (for testing)

I have created a server side route (using iron-router). Code is as follows :
Router.route( "/apiCall/:username", function(){
var id = this.params.username;
},{ where: "server" } )
.post( function(req, res) {
// If a POST request is made, create the user's profile.
//check for legit request
console.log('post detected')
var userId = Meteor.users.findOne({username : id})._id;
})
.delete( function() {
// If a DELETE request is made, delete the user's profile.
});
This app is running on port 3000 on my local. Now I have created another dummy app running on port 5000. Frrom the dummy app, I am firing a http.post request and then listening it on the app on 3000 port. I fire the http.post request via dummy app using the below code :
apiTest : function(){
console.log('apiTest called')
HTTP.post("http://192.168.1.5:3000/apiCall/testUser", {
data: [
{
"name" : "test"
}
]
}, function (err, res) {
if(!err)
console.log("succesfully posted"); // 4
else
console.log('err',err)
});
return true;
}
But I get the following error on the callback :
err { [Error: socket hang up] code: 'ECONNRESET' }
Not able to figure out whats the problem here.
The server side route is successfully called, but the .post() method is not being entered.
Using meteor version 1.6
192.168.1.5 is my ip addr
Okay so if I use Router.map function, the issue is resolved.
Router.map(function () {
this.route("apiRoute", {path: "/apiCall/:username",
where: "server",
action: function(){
// console.log('------------------------------');
// console.log('apiRoute');
// console.log((this.params));
// console.log(this.request.body);
var id = this.params.username;
this.response.writeHead(200, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
});
if (this.request.method == 'POST') {
// console.log('POST');
var user = Meteor.users.findOne({username : id});
// console.log(user)
if(!user){
return 'no user found'
}
else{
var userId = user._id;
}
}
});
});
It looks like the content type is not set the application/json. So you should do that...
Setting the "Content-Type" header in HTTP.call on client side in Meteor

Testing with meteor and jasmine: Iron Router Routing does not work as expected

I am trying to write tests for a meteor app with the velocity/jasmine framework.
My boss wants a UI testing (End-To-End) so I need to write tests for the User Interface.
I now have the problem how I should test the normal Navigation through the app. My Idea to test for example the user registration procedure was something like this:
describe 'Login and Usermanagement System', ->
it 'should say the user is logged out when no user is logged in', ->
# This test Works
expect(Meteor.user()).toBeFalsy()
it 'should show a welcome screen if the user is logged out', ->
currentUrl = Router.current().location.get().href;
routeName = Router.current().route.getName();
# This test Works as the startpage in our app (When you hit /) is always system.welcome as long as you are not logged in.
expect(routeName).toBe("system.welcome")
it 'should show a register screen if the user is logged out and clicked on register', (done) ->
Router.go("/register")
routeName = Router.current().route.getName()
# This test does not work as the Router.go seems to be async.
expect(routeName).toBe("system.register")
my problem is the third test. I need some kind of callback when a route has loaded to do the next stuff. Of yourse I could wait for 2 seconds or so, but this would slow down my tests unnecesarily.
Is there such a thing as Router.go(route, options, callback) or how can I get such a behaviour?
Technology we are using: MeteorJS with Iron Router for Routing, Velocity Test Framework with Jasmine for Testing.
You need to use the helper described here in the documentation Integration Tests With Iron Router
Which states:
Save this helper to tests/jasmine/client/integration/lib/wait_for_router_helper.js or tests/jasmine/client/unit/_wait_for_router_helper.js depending on the mode you want to use:
(function (Meteor, Tracker, Router) {
var isRouterReady = false;
var callbacks = [];
window.waitForRouter = function (callback) {
if (isRouterReady) {
callback();
} else {
callbacks.push(callback);
}
};
Router.onAfterAction(function () {
if (!isRouterReady && this.ready()) {
Tracker.afterFlush(function () {
isRouterReady = true;
callbacks.forEach(function (callback) {
callback();
});
callbacks = []
})
}
});
Router.onRerun(function () {
isRouterReady = false;
this.next();
});
Router.onStop(function () {
isRouterReady = false;
if (this.next) {
this.next();
}
});
})(Meteor, Tracker, Router);
Then you use it in your tests like this:
describe('My Spec', function () {
beforeEach(function (done) {
Router.go('/myPage');
Tracker.afterFlush(done);
});
beforeEach(waitForRouter);
it('should do something', function () {
// Your test
});
});

Meteor accounts verifyEmail

I am trying to make email verification that with the accounts-password package work however I have come across a weird problem.
It seems the # in the email verification URL is causing an issue. The verification email URL usually looks like : http://localhost:3000/#/verify-email/cnaTqQSCgYAksIsFo5FgmV94NHwrfaM2g5GvdZDUMlN
When I click on this, nothing seems to happen; it just re-directs to localhost:3000/#
However when I remove the # (http://localhost:3000/verify-email/cnaTqQSCgYAksIsFo5FgmV94NHwrfaM2g5GvdZDUMlN) this seems to work perfectly.
The URL (http://localhost:3000/#/verify-email/cnaTqQSCgYAksIsFo5FgmV94NHwrfaM2g5GvdZDUMlN) comes from Meteor so it's not something I create.
Here are my routes and controllers (using iron-router)
Router.route('/verify-email/:_token', {
controller : 'AccountController',
action : 'verifyEmail'
});
AccountController = RouteController.extend({
fastRender: true,
data: function () {},
onBeforeAction: function () {
this.render('Loading');
this.next();
},
verifyEmail: function() {
var verificationToken = this.params._token;
console.log(verificationToken);
Accounts.verifyEmail(verificationToken, function(error) {
if (error) {
console.log(error);
} else {
Router.go('/');
}
});
}
});
Any help is appreciated.
The conflict might be connected to the accounts-password package together with iron:router as outlined here:
...add a server file that overrides the urls with # paths that Meteor creates, so that the Iron-Router can work:
(function () {
"use strict";
Accounts.urls.resetPassword = function (token) {
return Meteor.absoluteUrl('reset-password/' + token);
};
Accounts.urls.verifyEmail = function (token) {
return Meteor.absoluteUrl('verify-email/' + token);
};
Accounts.urls.enrollAccount = function (token) {
return Meteor.absoluteUrl('enroll-account/' + token);
};
})();
Hope it will guide you in the right direction.

Resources