CodeceptJS and Nightmare - set cookie before suite in helper class - nightmare

I decided use framework CodeceptJS and library Nightmare.
Mine issue is set cookie before run all test suite
I read the documentation and understanding so for that to solve mine issue me need use helper classes. Maybe I'm wrong but still.
Perhaps you need to use a different approach if so let me know.
It mine helper
'use strict';
class SetCookie extends Helper {
constructor(config){
super(config)
}
_beforeSuite() {
this.client = this.helpers['Nightmare'].browser;
this.getCookies().then((cookies) => {
console.log(cookies);
})
}
getCookies(){
return this.client.cookies.get()
}
}
module.exports = SetCookie;
Problem
Cookies return after finished test suite

https://codecept.io/helpers/Nightmare/#setcookie
That is existing nightmare helper. Did you try it?

I solved this problem:
Mine Helper
async setSplitCookies() {
const client = this.helpers['Nightmare'];
const cookie = {
name: 'rc_web_spl',
value: 'on',
url: 'http://www.nic.ru'
}
return client.setCookie(cookie);
}
Mine test:
Before((I) => {
I.setSplitCookies();
});

Related

Axios/Fetch not using next.config.js rewrite

Looking up several examples online, it appears all one would need to do to redirect requests to the backend is to add rewrites to the next.config.js file, and it should work. However, I must be missing or misunderstanding something as this alone doesn't seem to do the trick. Redirecting seems to work if I type the url in the browser, but calls from axios/fetch continue to try to use a path relative to my client. Here are my snippets:
next.config.js
module.exports = {
async rewrites() {
return [
{
source: '/api',
destination: 'http://localhost:3001',
},
]
},
};
components/MyComponent.js
import React, { useEffect } from "react";
import axios from "axios";
function MyComponent({projectName}) {
...
useEffect(() => {
axios.get("/api/project/" + projectName)
.then((res) => {
console.log(res);
});
return;
}, []);
...
};
export default MyComponent;
To clarify, if I hit http://localhost:8001/api/project/Name_of_Project from the browser, I get properly redirected to my server (hosted on port 3001) and receive data I'd expect. However, when I hit my client (http://localhost:8001/Name_of_Project), axios doesn't redirect and tries http://localhost:8001/api/project/Name_of_Project which obviously fails. I also tried the fetch equivalent instead of axios and get the same result.
Is there another step that I need to take? Does the rewrite not work for axios/fetch? I have also seen mentions of the next-http-proxy-middleware package in my search, but I am not sure if this is something that I need to use in conjunction with the rewrite or not.
I appreciate any insight!
EDIT 1:
After doing some more searching, I ran into this post, and discovered that my issue is because I am using relative pathing in my axios call. If I change it to:
axios.get("http://localhost:3001/api/project/" + projectName)
.then((res) => {
console.log(res);
});
then I get my data properly. I suppose this leads me to my next question: is there a way to use relative path alongside the rewrite in the config? I personally think it's a little ugly to have the hostname and port exposed like that (I eventually plan on hosting this app on a FQDN). So if there's anything that can be done about that, I'd love to know!
EDIT 2: Of course the change in my first edit works because I am hitting my server directly! Which is not the desired effect. I want to use the redirect set in the config to go to my api.
Aha! I WAS misunderstanding something. I assumed that the path in the rewrite would reattached my path params for free. This is not the case. A link to the documentation.
The relevant excerpt:
Wildcard Path Matching
To match a wildcard path you can use * after a parameter, for example /blog/:slug* will match /blog/a/b/c/d/hello-world:
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // Matched parameters can be used in the destination
},
]
},
}
So my corrected next.config.js:
module.exports = {
async rewrites() {
return [
{
source: '/api/:slug*',
destination: 'http://localhost:3001/api/:slug*',
},
]
},
};

How can I test all this logic inside setState callback parameter

I'm trying to test the following code. I'm using jest and react testing library. This is the firs time I've used setState like this. I solved my initial which was to avoid passing in the dependency of current state but I'm not sure how can I test this. Can someone please advise.
useEffect(() => {
setUsers(currentUsers => {
if(currentUsers === undefined) {
return userDataFromApi;
} else {
//Users already exist in state
const mergedUserData = currentUsers.map(existingUser => {
const matchedUser = userDataFromApi.find(user => user.name === existingUser.name);
if (matchedUser) {
existingUser.stats = user.stats;
}
return existingUser;
});
return mergedUserData;
}
});
}, [setUsers, userDataFromApi]);
This piece of code is implementation detail. React testing library enforces UI testing. You can read this article from Kent Dodds.
In your tests you can do the same thing as the user would do (fill a form, click etc.), and then check what the user should see or not see (maybe his name, his stats etc.).
And if you get data from your backend and you would like to test only the frontend, you can mock the answer of the backend.

Can't get the Generic Sensor API to work in a React app

I'm trying to implement the Generic Sensor API in a React app.
https://www.w3.org/TR/generic-sensor/#the-sensor-interface
I keep getting an error when I try to implement any of the sensors in my code.
For example:
var sensor1 = new AmbientLightSensor();
I get the error: Cannot find name: 'AmbientLightSensor'.
I assume that I need an import statement in my code. All of the examples I've found only include LitElement. I've even tried that but still get the unknown error.
What import statements do I need in my typescript code?
What npm packages do I need?
Below is the typescript code I'm using.
I'm getting a typescript error:
/Users/scoleman/dev/current/bigbrother/src/utility/testAccel.ts(14,24):
Cannot find name 'AmbientLightSensor'. TS2304
export const testAccel = async (
databaseName: string,
) => {
const {state} = await navigator.permissions.query({
name: "ambient-light-sensor"
});
if (state !== "granted") {
console.warn("You haven't granted permission to use the light sensor");
return;
}
const sensor = new AmbientLightSensor();
sensor.addEventListener("reading", () => {
console.log(sensor.illuminance);
});
sensor.addEventListener("error", (err: any) => {
console.error(err);
});
sensor.start();
};
I was able to get these api's running using the polyfill at:
https://github.com/kenchris/sensor-polyfills
This would depend entirely on the browser you are using. I don't think FireFox supports it at the moment so I will focus on Chrome.
Firstly, you might need to be serving your site over HTTPS. It seems like this almost varies from permission to permission and also some are available on a localhost URL no matter what.
Secondly, for Chrome, you have to enable the "Generic Sensor Extra Classes" flag in Chrome at the chrome://flags/#enable-generic-sensor-extra-classes page.
Next, you need to make sure that have permission from the user to use the sensor, then you could actually use it. A snippet that would check that is as follows:
(async function(){
const {state} = await navigator.permissions.query({
name: "ambient-light-sensor"
});
if (state !== "granted") {
console.warn("You haven't granted permission to use the light sensor");
return;
}
const sensor = new AmbientLightSensor();
sensor.addEventListener("reading", () => {
console.log(sensor.illuminance);
});
sensor.addEventListener("error", err => {
console.error(err);
});
sensor.start();
}());

ReactJS + Cypress E2E testing

a quick question for anyone with React + Cypress experience - writing my first set of E2E tests and here's whats bugging me :
cy.visit('http://movinito.docker.localhost:3000/company/subcontractors');
works, but
cy.visit('/company/subcontractors');
doesn't work as expected (redirects me to the dashboard after login and stays there when I try to assert a pathname includes 'subcontractors').
my baseUrl in the cypress.json is
{"baseUrl": "http://react_frontend.movinito.docker.localhost:3000"}
and it generally works (in case that was what you suspected).
I would like to use the shorter, nicer version cy.visit('/company/subcontractors'); instead of the long winded retype of the baseUrl...
Might be important to add that prior to the .visit I use a
cy.request('POST', 'http://movinito.docker.localhost/user/login?_format=json', {name,pass});
to [successfully] log in... As I said the whole thing works but I can't make use of the baseUrl and have to use the .visit command with the full environement based url...
Here is the [working] full test code
describe('Subcontractors section', ()=> {
it('renders properly', ()=> {
const { name, pass } = {name: 'info#batcave.com', pass: '123#456'}
cy.request('POST', 'http://movinito.docker.localhost/user/login?_format=json', {
name,
pass
});
cy.visit('http://movinito.docker.localhost:3000/company/subcontractors');
//
// I want to replace the above line with cy.visit('/company/subcontractors')
//
cy.location('pathname').should('include', '/company/subcontractors');
cy.get('[data-cy=page-title]').should('have.text', 'Subcontractors');
})
});
hmm, I read the documentation about visit() and request(), this should work to:
describe('Subcontractors section', ()=> {
it('renders properly', ()=> {
cy.visit({
url: 'http://movinito.docker.localhost/user/login?_format=json',
method: 'POST',
body {
name,
pass
}
})
cy.visit('/company/subcontractors')
cy.location('pathname').should('include', '/company/subcontractors')
})
});
// cypress.json
{
"baseUrl": "http://react_frontend.movinito.docker.localhost:3000"
}

FeathersJS custom API method that retrieves enum Type, to fill a Dropdown in React

So I'm trying to fill a select component with a enum type from mongoose
In my user service the schema looks something like :
firstName: { type:String, required: true },
...
ris:{type: String, default: 'R', enum:['R', 'I', 'S']},
In my feathers service I can access the Model with "this.Model"
so in any hook I can do:
this.Model.schema.path('ris').enumValues); //['R','C','I']
and I get the values from the enum type.
Now since I can't create custom API methods other that the officials ones
Feathers calling custom API method
https://docs.feathersjs.com/clients/readme.html#caveats
https://docs.feathersjs.com/help/faq.html#can-i-expose-custom-service-methods
How can I create a service method/call/something so that I can call it in my
componentDidMount(){ var optns= this.props.getMyEnumsFromFeathers}
and have the enum ['R','C','I'] to setup my dropdown
I'm Using React/Redux/ReduxSaga-FeathersJS
I'd create a service for listing Enums in the find method:
class EnumService {
find(params) {
const { service, path } = params.query;
const values = this.app.service(service).Model.schema.path(path).enumValues;
return Promise.resolve(values);
}
setup(app) {
this.app = app;
}
}
app.use('/enums', new EnumService())
Then on the client you can do
app.service('enums').find({ query: {
service: 'myservice',
path: 'ris'
}
}).then(value => console.log('Got ', values));
I was trying to use this code, but, it does not work like plug and play.
after some play with the app service I figured out the code below
async find(params) {
const { service, path } = params.query;
const values = await this.app.service(service).Model.attributes[path].values;
return values || [];
}
setup(app) {
this.app = app;
}
I am not sure if it is a thing of what database is been used, in my case I am in development environment, so, I am using sqlite.

Resources