Set request header in Protractor - protractor

Is it possible to set request headers in Protractor?
In the following post (2014), Protractor confirmed that currently they don't have any way to do this (as protractor was not designed to interact with under-the-hood things.
here
Has anyone found out a way how to do this?
Thanks in advance :)

I had the same problem so I implemented a simple proxy to inject headers in the requests. I published it on npm repository. You can find it here https://www.npmjs.com/package/headers-injection-proxy
Very easy to use:
header-injection-proxy -p 3000 -t "https://www.google.com" -h "headers.json"
At that point you just send the requests to the proxy instead of the real server

You can use an external library like request. For me it worked as a charm with Protractor:
https://github.com/request/request#custom-http-headers
EDIT:
Here you have an example of implementation. It uses request-promise
import {browser} from 'protractor';
import {put} from 'request-promise';
import {ADMIN_URL} from '../data/definitions/urls';
export class CreateUser {
public setRoles(username: string, roles: string[]) {
return this.getUserId(username).then((userId) => {
const data = {
url: `${ADMIN_URL}/user/${userId}/role`,
headers: {
Authorization: browser.params.token
},
body: roles,
json: true,
rejectUnauthorized: false
};
return put(data);
});
}
}

Related

Using Mongodb Adapter in NextAuth not working

I git clone & copy MUI Nextjs example project & start from there.
From NextAuth portal, they said I can just copy mongodb adapter setup here and basically it will work well out of the box. I placed this file in this path: /src/lib/mongodb.js
Here I'm using CredentialsProvider. Basically I'm using my own form for login & authentication process.
Here my /pages/api/auth/[...nextauth].js file:
import { MongoDBAdapter } from "#next-auth/mongodb-adapter";
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import clientPromise from "../../../src/lib/mongodb";
export default NextAuth({
secret: process.env.SECRET,
adapter: MongoDBAdapter(clientPromise),
providers: [
CredentialsProvider({
async authorize(credentials) {
const { email, password } = credentials
if(email !== 'test#test.com' || password !== 'password123') {
throw new Error('User does not exists. Please make sure you insert the correct email & password.')
}
return {
id: 1,
name: 'Tester',
email: 'test#test.com'
}
}
})
],
callbacks: {
redirect: async ({ url, baseUrl }) => {
return baseUrl
}
}
})
What I understood, I can just straight away use this adapter & it will create 4 models/tables (User, Session, Account, VerificationToken) by default. So I don't need to create them myself. Ref doc here
According to the NextAuth MongoDB Adapter documentation, I just need to specify the MONGODB_URI in .env.local.
so here my /.env.local file content:
NEXTAUTH_URL=http://localhost:3000
MONGODB_URI=mongodb+srv://<username>:<password>#rest.lvnpm.mongodb.net/<database_name>?retryWrites=true&w=majority
SECRET=someSecret
NODE_ENV=development
So currently, it does nothing at all. I don't need to specify session.strategy to database since by default NextAuth will recognized that if I use adapter option.
What do I need to do here to make this work? Any helps is appreciated. Here my github project
I just found out that in NextAuth, if I use CredentialsProvider. I won't be able to persist data using database strategy. You may go here to NextAuth documentation itself to know why

Ionic CORS issue with JIRA API

Problem description : I have built a ionic app which uses JIRA rest api to fetch issue (GET data), create issue (POST data). I always get CORS error's like preflight request did not succeed or same origin policy which are expected when we use ionic serve but the same is not working when I build and release the signed apk.
My ionic server runs on localhost:8100 (ionic version -4) &
Jira server runs on localhost:8089 (JIRA version - core 7)
What I have done so far :
followed the proxy approach as mentioned in ionic blog --No success
enabled CORS filter plugin in JIRA server and whitelisted ionic server --No success
Added headers for Allow control origin -- No success
Build the apk file using --prod release signed and tried the same on device --No sucess
Here is my auth.ts file reference if any-one can help and advise here about what I am doing wrong here.
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { AuthProvider } from '../auth/auth';
import { Issue } from '../../models/issue'
#Injectable()
export class JiraProvider {
apiVersion: string = '2'; // The API version we want to use
jiraInstanceUrl: string = 'http://localhost:8089' // The Jira instance URL
urlString: string = `${this.jiraInstanceUrl}/rest/api/${this.apiVersion}`; // Concat those together
constructor(
public http: HttpClient,
public auth: AuthProvider
) {
}
// Authenticate the user against Jira's profile endpoint.
public authenticateUser(username: string, password: string): Observable<Object> {
return this.http.get(`${this.urlString}/myself`, {
headers: new HttpHeaders()
.append('Authorization', `Basic ${btoa(username + ':' + password)}`)
.append("Access-Control-Allow-Origin","*")
});
}
// Get issue details based on the provided key.
public getIssue(key: string): Observable<Issue> {
return this.http.get<Issue>(`${this.urlString}/issue/${key}`, {
headers: new HttpHeaders()
.append('Authorization', `Basic ${this.auth.getAuthString()}`)
.append("Access-Control-Allow-Origin","*")
});
}
public getAllIssue():Observable<any> {
return this.http.get(`${this.urlString}/search?jql=project=PM`,{
headers: new HttpHeaders()
.append('Authorization', `Basic ${this.auth.getAuthString()}`)
.append("Access-Control-Allow-Origin","*")
});
}
public postIssue(data):Observable<any>{
return this.http.post(`${this.urlString}/issue`,JSON.stringify(data),{
headers: new HttpHeaders()
.append('Authorization', `Basic ${this.auth.getAuthString()}`)
.append('Content-Type','application/json')
.append("X-Atlassian-Token", "no-check")
.append("User-Agent", "xx")
.append("Access-Control-Allow-Origin","*")
});
}
}
Added screenshot as per request(please not I changed the JIRA server intentionally to 8089 updated the question accordingly)
I soved this issue by using a CORS proxy in a container (Docker) for when you need to Access-Control-Allow-Origin: *`! this acts like a proxy https://github.com/imjacobclark/cors-container and now I am able to route the requests.
Hope it helps others !!

Service in vue2JS - error in created hook

I'm new to vue2JS and currently I am trying to create my very first service in vue2 ever.
I've created basic file api.js with this code:
import axios from 'axios';
export default () => {
return axios.create({
baseURL: 'http://localhost:8080/',
timeout: 10000,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
})
}
Code above is basic axios configuration which will be used in every service across entire app.
I import this file into my service:
import api from '../api.js';
export default {
getLatest () {
return api().get(`http://localhost/obiezaca/ob_serwer/api/article/getLatest.php`, {
headers: {
'Content-Type': 'application/json'
}
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
}
}
Code above is responsible for making http request to backend rest API which give JSON in response.
And then finally I want to use this service inside my component <script></script> tags:
<script>
import { getLatest } from '../../../services/articles/getLatest';
export default {
data () {
return {
articles: []
}
},
created () {
const getLatestService = new getLatest();
console.log(getLatestService);
}
}
</script>
Here I want to execute code from service and actually execute this http request then save response in getLatestService constant and then console.log it and I should be able to see JSON in my browser console.
This doesn't work and give me this error in chrome console:
[Vue warn]: Error in created hook: "TypeError: WEBPACK_IMPORTED_MODULE_0__services_articles_getLatest.a is not a constructor"
And this error in command line:
39:35-44 "export 'getLatest' was not found in '../../../services/articles/getLatest'
Please help me to solve this problem. Additionally I want to refactor my code from service (second one) to use async await but I just can't find good example which would show me way to accomplish that.
EDIT 22.11.17
I added error which show in command line and { } when importing in component. I still didn't solve the problem.
EDIT 24.11.17
Looking for an answer I add more explanation of code I've posted and screenshot of files structure if maybe it can help.
I have check your code and what i can see is, in your api.js you have used
baseURL: 'http://localhost:8080/',
and in your service file
return api().get(`http://localhost/obiezaca/ob_serwer/api/article/getLatest.php`
In your service file you have not define your localhost port, i think it should be like
return api().get(http://localhost:8080/obiezaca/ob_serwer/api/article/getLatest.php
If above is not an your issue then you should try
const getLatestService = getLatest();
Because getLatest() is a function and not an object.
This might solve your error issue.

How to use Ionic proxy in conjunction with AWS SDK

Using Ionic 4.4.0 and aws-sdk 2.157.0. I'm trying to create an S3 bucket from my local web browser, but am running into CORS problems when attempting to run the following code, method createBucketByCompanyKey():
import { Injectable } from '#angular/core';
import * as AWS from 'aws-sdk';
#Injectable()
export class AwsProvider {
private accessKeyId:string = 'myAccessKey';
private secretAccessKey:string = 'mySuperSecret';
private region:string = 'us-east-1';
constructor() {
AWS.config.update({accessKeyId: this.accessKeyId, secretAccessKey: this.secretAccessKey, region: this.region});
}
createBucketByCompanyKey(companyKey){
let s3 = new AWS.S3();
let params = {
Bucket: companyKey,
CreateBucketConfiguration: {
LocationConstraint: this.region
}
};
s3.createBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
}
}
This gives me the error
Failed to load https://s3.amazonaws.com/-KwzdjmyrHiMBCqHH1ZC: Response
to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8100' is therefore not allowed
access. The response had HTTP status code 403.
Which led me to this post here after several hours of googling. It appears I need to run ionic through a proxy. I've also tried changing my "path" to http://localhost:8100, but stuck I remain.
{
"name": "MyApp",
"app_id": "",
"type": "ionic-angular",
"integrations": {},
"proxies": [
{
"path": "/",
"proxyUrl": "https://s3.amazonaws.com/"
}
]
}
I've also come across posts telling my to download a Chrome extension that disables CORS, but that didn't work either.
Any ideas on how to setup this proxy to work with AWS' SDK?
Forget the proxies. For Mac, enter in the following in the terminal to open a Google Chrome browser with CORS disabled.
open -a Google\ Chrome --args --disable-web-security --user-data-dir
Compliments of this post.

Using Grunt to Mock Endpoints

I'm using Yeoman, Grunt, and Bower, to construct a platform for building a frontend independently of a a backend. The idea would be that all of my (AngularJS) controller, services, factories, etc live in this project, and get injected afterwards into my serverside codebase based off the result of grunt build.
My question is:
How can I mock endpoints so that the Grunt server responds to the same endpoints as my (Rails) App will?
At the moment I am using:
angular.module('myApp', ['ngResource'])
.run(['$rootScope', function ($rootScope) {
$rootScope.testState = 'test';
}]);
And then in each of my individual services:
mockJSON = {'foo': 'myMockJSON'}
And on every method:
if($rootScope.testState == 'test'){
return mockJSON;
}
else {
real service logic with $q/$http goes here
}
Then after grunt build, testState = 'test' gets removed.
This is clearly a relatively janky architecture. How can I avoid it? How can I have Grunt respond to the same endpoints as my app (some of which have dynamic params) apply some logic (if necessary), and serve out a json file (possibly dependent on path params)?
I've fixed this issue by using express to write a server that responds with static json.
First I created a directory in my project called 'api'. Within that directory I have the following files:
package.json:
{
"name": "mockAPI",
"version": "0.0.0",
"dependencies": {
"express": "~3.3.4"
}
}
Then I run npm install in this directory.
index.js:
module.exports = require('./lib/server');
lib/server.js:
express = require('express');
var app = express();
app.get('/my/endpoint', function(req, res){
res.json({'foo': 'myMockJSON'});
});
module.exports = app
and finally in my global Gruntfile.js:
connect: {
options: {
port: 9000,
hostname: 'localhost',
},
livereload: {
options: {
middleware: function (connect, options) {
return [
lrSnippet,
mountFolder(connect, '.tmp'),
mountFolder(connect, yeomanConfig.app),
require('./api')
];
}
}
},
Then the services make the requests, and the express server serves the correct JSON.
After grunt build, the express server is simply replaced by a rails server.
As of grunt-contrib-connect v.0.7.0 you can also just add your custom middleware to the existing middleware stack without having to manually rebuild the existing middleware stack.
livereload: {
options: {
open: true,
base: [
'.tmp',
'<%= config.app %>'
],
middleware: function(connect, options, middlewares) {
// inject a custom middleware into the array of default middlewares
middlewares.push(function(req, res, next) {
if (req.url !== '/my/endpoint') {
return next();
}
res.writeHead(200, {'Content-Type': 'application/json' });
res.end("{'foo': 'myMockJSON'}");
});
return middlewares;
}
}
},
See https://github.com/gruntjs/grunt-contrib-connect#middleware for the official documentation.
Alternatively you can use the grunt-connect-proxy to proxy everything that is missing in your test server to an actual backend.
It's quite easy to install, just one thing to remember when adding proxy to your livereload connect middleware is to add it last, like this:
middleware: function (connect) {
return [
lrSnippet,
mountFolder(connect, '.tmp'),
mountFolder(connect, yeomanConfig.app),
proxySnippet
];
}
grunt-connect-prism is similar to the Ruby project VCR. It provides an easy way for front end developers to record HTTP responses returned by their API (or some other remote source) and replay them later. It's basically an HTTP cache, but for developers working on a Single Page Application (SPA). You can also generate stubs for API calls that don't exist, and populate them the way you want.
It's useful for mocking complex & high latency API calls during development. It's also useful when writing e2e tests for your SPA only, removing the server from the equation. This results in much faster execution of your e2e test suite.
Prism works by adding a custom connect middleware to the connect server provided by the grunt-contrib-connect plugin. While in 'record' mode it will generate a file per response on the filesystem with content like the following:
{
"requestUrl": "/api/ponies",
"contentType": "application/json",
"statusCode": 200,
"data": {
"text": "my little ponies"
}
}
DISCLAIMER: I'm the author of this project.
You can use Apache proxy and connect your REST server with gruntjs.
Apache would do this:
proxy / -> gruntjs
proxy /service -> REST server
you would use your application hitting Apache and angular.js application would think that is talking with itself so no cross domain problem.
Here is a great tutorial on how to set this up:
http://alfrescoblog.com/2014/06/14/angular-js-activiti-webapp-with-activiti-rest/
Just my alternative way that based on Abraham P's answer. It does not need to install express within 'api' folder. I can separate the mock services for certain files. For example, my 'api' folder contains 3 files:
api\
index.js // assign all the "modules" and then simply require that.
user.js // all mocking for user
product.js // all mocking for product
file user.js
var user = function(req, res, next) {
if (req.method === 'POST' && req.url.indexOf('/user') === 0) {
res.end(
JSON.stringify({
'id' : '5463c277-87c4-4f1d-8f95-7d895304de12',
'role' : 'admin'
})
);
}
else {
next();
}
}
module.exports = user;
file product.js
var product = function(req, res, next) {
if (req.method === 'POST' && req.url.indexOf('/product') === 0) {
res.end(
JSON.stringify({
'id' : '5463c277-87c4-4f1d-8f95-7d895304de12',
'name' : 'test',
'category': 'test'
})
);
}
else {
next();
}
}
module.exports = product;
index.js just assigns all the "modules" and we simply require that.
module.exports = {
product: require('./product.js'),
user: require('./user.js')
};
My Gruntfile.js file
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: 'localhost',
livereload: 35729
},
livereload: {
options: {
open: true,
middleware: function (connect) {
return [
connect.static('.tmp'),
connect().use(
'/bower_components',
connect.static('./bower_components')
),
connect.static(appConfig.app),
require('./api').user,
require('./api').product,
];
}
}
}