URLS Redirects with Cypress automation - cypress

I passed 100+ URLs path(legacy) in the scenario outlines and i want to hit each one of them and to redirect to a new path(new).
I passed a code like below;
function createNewUrlFromLegacy(legacyPageUrl) {
const urlPath = legacyPageUrl.split('/');
let newUrl;
if (urlPath.length == 7) {
newUrl = 'new-homes/' + urlPath[5];
} else {
newUrl = 'new-homes/' + urlPath[0];
}
return newUrl
}
I passed this following in my stepDef file
const expectedUrl = createNewUrlFromLegacy(legacyUrl);
cy.url().should('include', expectedUrl);
And it run successfully.
But i want to use response code 301 as an assertion instead relying on expectedUrl only.
How can i do this pls?.

I have managed to get it working using the following steps;
First visit the legacy url and then set followRedirects: false using alias.
cy.visit(legacyUrl);
cy.request({url: legacyUrl, followRedirect: false}).as('response');`
cy.get('#response').its('status').should('eq', 301); --> Assert Response code is 301
cy.get('#response').its('redirectedToUrl').should('contain', expectedUrl); -->Assert expected URL is displayed.

Related

Firefox extension proxy

I am trying to create a Firefox extension to block search terms on school computers. I'd like to prohibit a list of keywords, but the blocking doesn't seem to be working.
I found an example through a plugin gallery here:
https://github.com/mdn/webextensions-examples/blob/master/proxy-blocker/background/proxy-handler.js
This plugin listens to blocked hosts, and then basically returns localhost. I'd like to do the same, but when search terms are added in. I used the code in the example above as a starting point.
Here is the code I have so far:
// Initialize the list of blocked hosts
let blockedHosts = ["www.duckduckgo.com", "www.google.com"];
let blockedTerms = ["games", "minecraft", "legos"];
// Set the default list on installation.
browser.runtime.onInstalled.addListener(details => {
browser.storage.local.set({
blockedHosts: blockedHosts
});
});
// Get the stored list
browser.storage.local.get(data => {
if (data.blockedHosts) {
blockedHosts = data.blockedHosts;
}
});
// Listen for changes in the blocked list
browser.storage.onChanged.addListener(changeData => {
blockedHosts = changeData.blockedHosts.newValue;
});
// Managed the proxy
// Listen for a request to open a webpage
browser.proxy.onRequest.addListener(handleProxyRequest, {urls: ["<all_urls>"]});
function handleProxyRequest(requestInfo) {
let urlToCheck = new URL(requestInfo.documentUrl)
let searchString = urlToCheck.search;
const url = new URL(requestInfo.url);
let found;
blockedTerms.map((term) =>{
if(searchString.search(term) != -1){
found = true
}
})
if ( blockedHosts.indexOf(url.hostname) != -1 & found) {
return {type: "https", host: "127.0.0.1", port: 65535};
}
// Return instructions to open the requested webpage
return {type: "direct"};
}
// Log any errors from the proxy script
browser.proxy.onError.addListener(error => {
console.error(`Proxy error: ${error.message}`);
});
The URL that the browser creates is https://duckduckgo.com/?t=ffab&q=games&ia=web for example. I can determine that the term "games" was found, and that it was found in a duck duck go search, but the proxy wont work and the browser wont stop the user from going to the page.
Any help would be appreciated!
To start with, in a school environment, I suppose they have to use school net connection. It would be a lot easier to block at the main internet connection instead of creating and installing an addon on each computer (that might be altered or bypassed with another browser).
However, to answer your question, the following would be one (simpler) way of doing that using webRequest.onBeforeRequest:
// add a listener for web requests
browser.webRequest.onBeforeRequest.addListener(process, {
urls: ['*://*/*']
},
['blocking']
);
function process(e) {
// e.url is the target url
// no need for storage as the filter-list is hard-coded
const blockedHosts = ['www.duckduckgo.com', 'www.google.com'];
const blockedTerms = ['games', 'minecraft', 'legos'];
const hostRegExp = new RegExp(`^https?://(${blockedHosts.join('|')})/`, 'i');
const termRegExp = new RegExp(`(${blockedTerms.join('|')})`, 'i');
// if matches above criteria, redirect to 127.0.0.1
if (hostRegExp.test(e.url) && termRegExp.test(e.url)) {
return {redirectUrl: 'https://127.0.0.1:65535/'};
}
}

vuejs can't set new data

getSlideShow: function () {
this.$http.post(api||web).then((response) => {
// console.log(response.data);` return path success
if (response.data[0]) {
console.log(response.data[0].file); // check link ok
this.image_slide_1 = path + response.data[0].file;
}
if (response.data[1]) {
console.log(this.image_slide_1); data changed
this.image_slide_2 = path + response.data[1].file;
}
}
}
<img :src="image_slide_1"
if me set data before request
`this.data = ... `
`this.$http.post()`
// image show
but set data in request http sound not work
and where login set data before request still work (even set data after request), but logout that not work
i have lost quite some time and to no avail, any suggestions to modify it

Cypress + 2 Super Domains + AntiforgeryToken = Cypress can't be redirect

I am currently working on setting-up a Cypress solution to test a product based on Nuxt and .NET. The product uses an SSO-based login page with a different super domain from the product.
This creates a problem with cookies. Indeed, access to the product generates a redirection to the SSO authentication page. And, following the validation of the authentication form, Chrome driven by Cypress enters a call loop with errors in the attributes of the cookie, in particular the value of the SameSite attribute which is incorrect compared to the expectation SSO side.
Currently, several features are disabled in the browser, namely :
SameSiteByDefaultCookies
CrossSiteDocumentBlockingIfIsolating
CrossSiteDocumentBlockingIfIsolating
IsolateOrigins
site-per-process
Excerpt of cypress/plugins/index.js
on('before:browser:launch', (browser = {}, launchOptions) => {
if (browser.family === 'chromium') {
launchOptions.args.push(
"--disable-features=SameSiteByDefaultCookies,CrossSiteDocumentBlockingIfIsolating,CrossSiteDocumentBlockingIfIsolating,IsolateOrigins,site-per-process"
);
}
console.log(launchOptions.args);
return launchOptions
});
Even by disabling all the protections on the SSO, no way to make Cypress work.
Here is an Excel file with all of the HTML requests listed via the Chrome console. The file describes the differences between the Chrome driven by Cypress and a "classic" Chrome.
NB: adding "chromeWebSecurity": false, in the configuration of Cypress does not change anything
Not fully knowing what the underlying concerns are, I cannot describe the problem well. All the solutions proposed to similar problems exposed on various forums (StackOverFlow included) were not enough to solve mine. Can you help me please ?
Thanks in advance.
Regards,
Alexander.
This may have been caused by the chrome 94 update, which came out in October 21. Update 94 removed the SameSiteByDefaultCookies flag, so that fix no longer works.
If you're having the same issue I was, I resolved it by intercepting all requests, checking if they had a set-cookie header(s) and rewriting the SameSite attribute. There's probably a neater way to do it, as this does clutter up the cypress dashboard a little. You can add this as a command for easy reuse:
In your commands file:
declare namespace Cypress {
interface Chainable<Subject> {
disableSameSiteCookieRestrictions(): void;
}
}
Cypress.Commands.add('disableSameSiteCookieRestrictions', () => {
cy.intercept('*', (req) => {
req.on('response', (res) => {
if (!res.headers['set-cookie']) {
return;
}
const disableSameSite = (headerContent: string): string => {
return headerContent.replace(/samesite=(lax|strict)/ig, 'samesite=none');
}
if (Array.isArray(res.headers['set-cookie'])) {
res.headers['set-cookie'] = res.headers['set-cookie'].map(disableSameSite);
} else {
res.headers['set-cookie'] = disableSameSite(res.headers['set-cookie']);
}
})
});
});
Usage:
it('should login using third party idp', () => {
cy.disableSameSiteCookieRestrictions();
//add test body here
});
or alteratively, run it before each test:
beforeEach(() => cy.disableSameSiteCookieRestrictions());
I finally found the solution for this SSO authentication.
Here is the code:
Cypress.Commands.add('authentificationSSO', (typedeCompte, login) => {
let loginCompte = 'login';
let motDePasseCompte = 'password';
let baseUrlSSO = Cypress.env('baseUrlSSO') ? Cypress.env('baseUrlSSO') : '';
let baseUrl = Cypress.config('baseUrl') ? Cypress.config('baseUrl') : '';
cy.request(
'GET',
baseUrlSSO +
'/Account/Login?${someParameters}%26redirect_uri%3D' +
baseUrl
).then((response) => {
let requestVerificationToken = '0';
let attributsCookieGroupe = [];
let nomCookie = '';
let tokenCookie = '';
const documentHTML = document.createElement('html');
documentHTML.innerHTML = response.body;
attributsCookieGroupe = response.headers['set-cookie'][0].split(';');
const loginForm = documentHTML.getElementsByTagName('form')[0];
const token = loginForm.querySelector('input[name="__RequestVerificationToken"]')?.getAttribute('value');
requestVerificationToken = token ? token : '';
nomCookie = attributsCookieGroupe[0].split('=')[0];
tokenCookie = attributsCookieGroupe[0].split('=')[1];
cy.setCookie(nomCookie, tokenCookie, { sameSite: 'strict' });
cy.request({
method: 'POST',
url:
baseUrlSSO +
'/Account/Login?{someParameters}%26redirect_uri%3D' +
baseUrl,
followRedirect: false,
form: true,
body: {
Login: loginCompte,
Password: motDePasseCompte,
__RequestVerificationToken: requestVerificationToken,
RememberLogin: false
}
});
});
});

Does Google Script have an equivalent to python's Session object?

I have this python script and I want to get Google Script equivalent but I do not know how to "pass" whatever needs to be passed between next get or post request once I log in.
import requests
import json
# login
session = requests.session()
data = {
'LoginName': 'name',
'Password': 'password'
}
session.post('https://www.web.com/en-CA/Login/Login', data=data)
session.get('https://www.web.com//en-CA/Redirect/?page=Dashboard')
# get customer table
data = {
'page': '1',
'pageSize': '100'
}
response = session.post('https://www.web.com/en-CA/Reporting', data=data)
print(response.json())
I wonder if there is an equivalent to .session() object from python's requests module. I did search google but could not find any working example. I am not a coder so I dot exactly know that that .session() object does. Would it be enough to pass headers from response when making new request?
UPDATE
I read in some other question that Google might be using for every single UrlFetchApp.fetch different IP so login and cookies might not work, I guess.
I believe your goal as follows.
You want to achieve your python script with Google Apps Script.
Issue and workaround:
If my understanding is correct, when session() of python is used, the multiple requests can be achieved by keeping the cookie. In order to achieve this situation using Google Apps Script, for example, I thought that the cookie is retrieved at 1st request and the retrieved cookie is included in the request header for 2nd request. Because, in the current stage, UrlFetchApp has no method for directly keeping cookie and using it to the next request.
From above situation, when your script is converted to Google Apps Script, it becomes as follows.
Sample script:
function myFunction() {
const url1 = "https://www.web.com/en-CA/Login/Login";
const url2 = "https://www.web.com//en-CA/Redirect/?page=Dashboard";
const url3 = "https://www.web.com/en-CA/Reporting";
// 1st request
const params1 = {
method: "post",
payload: {LoginName: "name", Password: "password"},
followRedirects: false
}
const res1 = UrlFetchApp.fetch(url1, params1);
const headers1 = res1.getAllHeaders();
if (!headers1["Set-Cookie"]) throw new Error("No cookie");
// 2nd request
const params2 = {
headers: {Cookie: JSON.stringify(headers1["Set-Cookie"])},
followRedirects: false
};
const res2 = UrlFetchApp.fetch(url2, params2);
const headers2 = res2.getAllHeaders();
// 3rd request
const params3 = {
method: "post",
payload: {page: "1", pageSize: "100"},
headers: {Cookie: JSON.stringify(headers2["Set-Cookie"] ? headers2["Set-Cookie"] : headers1["Set-Cookie"])},
followRedirects: false
}
const res3 = UrlFetchApp.fetch(url3, params3);
console.log(res3.getContentText())
}
By this sample script, the cookie can be retrieved from 1st request and the retrieved cookie can be used for next request.
Unfortunately, I have no information of your actual server and I cannot test for your actual URLs. So I'm not sure whether this sample script directly works for your server.
And, I'm not sure whether followRedirects: false in each request is required to be included. So when an error occurs, please remove it and test it again.
About the method for including the cookie to the request header, JSON.stringify might not be required to be used. But, I'm not sure about this for your server.
Reference:
Class UrlFetchApp
You might want to try this:
var nl = getNewLine()
function getNewLine() {
var agent = navigator.userAgent
if (agent.indexOf("Win") >= 0)
return "\r\n"
else
if (agent.indexOf("Mac") >= 0)
return "\r"
return "\r"
}
pagecode = 'import requests
import json
# login
session = requests.session()
data = {
\'LoginName\': \'name\',
\'Password\': \'password\'
}
session.post(\'https://www.web.com/en-CA/Login/Login\', data=data)
session.get(\'https://www.web.com//en-CA/Redirect/?page=Dashboard\')
# get customer table
data = {
\'page\': \'1\',
\'pageSize\': \'100\'
}
response = session.post(\'https://www.web.com/en-CA/Reporting\', data=data)
print(response.json())'
document.write(pagecode);
I used this program

Issues sending requests using fetch

I am using FETCH to make GET requests. I am also using NGROK for HTTP tunneling. My problem is here when I use var url = 'http://localhost:9090/test-message', I get a response but when I use
https://c2f2493e.ngrok.io/test-message I don't get a response. I don't know what the problem might be here.
Here is the full code:
fetch(url).then(function(response) {
console.log(response)
})
This url var url = 'http://localhost:9090/test-message ' does not have any Get Method request.
You May try Like this
function myFunction() {
var str = "http://localhost:9090/test-message";
var res = str.split("/");
res = res.reverse();
alert(res[0]); //text-message
}

Resources