When I test my angular app I need to reset some server data, so I tried to make an HTTP DELETE request before each test:
test.beforeEach(async ({ page }) => {
const reply = await page.evaluate(async () => {
return await fetch("https://localhost:44302/api/cleanup", { method: "DELETE" });
});
jsome(reply);
});
and I get the following error:
page.evaluate: Evaluation failed: TypeError: Failed to fetch
How can I do this before running my tests with Playwright?
Related
Issue
I have a MediaRecorder video of up to 400 KB that I need to send to the server.
I want to be able to also send the video when someone exits the page.
My code looks kind of like this:
window.onpagehide = (e) => {
e.preventDefault();
var blob = new Blob(this.data, {type: "video/mp4"});
var file = new File([blob], "recording");
var formData = new FormData();
formData.append("recording", file);
axios.post('my-site-url', formData)
.then(function (response) {
if(response.data.result) {
console.log("email has been sent")
} else {
console.log("failed to send email")
}
})
.catch(({response}) => {
console.log("an error occured during email call");
console.error(response);
})
return null;
}
However window.onpagehide doesn't allow async functions so axios.post isn't running at all.
NB: this issue is tested only on IOS Safari.
For Chrome and Edge I am using onbeforeunload and it works fine
Question
What synchronous axios.post alternative can I use for this scenario?
What I tried
navigator.sendBeacon
It looked pretty promising, but it has a limit of 64KB, so I couldn't rely on it.
fetch
fetch('my-site-url', {
method: 'POST',
body: formData
});
error message:
Fetch API cannot load my-site-url due to access control checks.
ajax
$.ajax({
type: 'POST',
async: false,
url: "my-site-url",
data: formData,
processData: false,
timeout: 5000,
});
error message:
XMLHttpRequest cannot load my-site-url due to access control checks.
XMLHttpRequest
var request = new XMLHttpRequest();
request.open('POST', 'my-site-url', false);
request.send(formData);
if (request.status === 200) {
console.log("success!");
}
error message:
XMLHttpRequest cannot load my-site-url due to access control checks.
But these are not CORS related issues, as they only happen when inside onpagehide on Safari.
I want to send parallel POST requests in puppeteer. I have to change the payload with every request (URL remains the same).
I tried using puppeteer cluster, but how do I change payload with every request when I queue the same request?
Using normal puppeteer
(async() => {
const browser = await puppeteer.launch({
args: [
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-web-security",
],
executablePath: 'C:/Program Files/..',
headless: false,
});
for(const id of Ids) {
const page = await browser.newPage();
await page.setDefaultNavigationTimeout(60000);
await page.evaluateOnNewDocument(() => {
// Some code
})
await page.setRequestInterception(true);
// Request intercept handler... will be triggered with
// each page.goto() statement
page.on('request', interceptedRequest => {
// Here, is where you change the request method and
// add your post data
var data = {
'method': 'POST',
'postData': JSON.stringify({
....
"similarMaterialId": `${id}`,
}),
'headers': {
.....
},
};
// Request modified... finish sending!
interceptedRequest.continue(data);
});
const response = await page.goto('https://.../getProductInfo');
const responseBody = await response.json();
try {
let title = responseBody.description;
let price = responseBody.price;
fs.appendFile('temp.tsv', `${title}\t${price}\n`, function (err) {
if (err) throw err;
})
}
catch {
console.log(id)
}
await page.close();
}
console.log("Code ended!!")
await browser.close();
})();
I want to create many pages in parallel on a single browser.
I want to do what the MS Graph sample node app is doing in its integrationTests.js, but that test doesn't work. Here's what I've tried:
Followed the quick start for creating a node.js app.
Ran the app. Ensured it worked by sending an e-mail.
Modified the test Checking that the sample can send an email to use my account parameters.
Tried to run the test. It fails with 403: insufficient scope. The call to get the token returned scopes, but lacked Mail.Send.
In the post data for the call to login.microsoftonline.com, I added "scope: 'Mail.Send'"
I still receive a valid token, and the return scope includes Mail.Send, but when I try to post with that token, I get 400: cannot POST /beta/me/sendMail
I tried adding scope (Mail.Send) in the query string and as a header (thought I saw that somewhere), but it made no difference.
I added the Mail.Send permission (under "Application Permissions") for the app in the application registration portal.
I compared the token (using https://jwt.ms) from my test call to the call from the app when it works. I see no real difference. They both contain the Mail.Send scope.
Here is the code (which is only slightly different from what's in the sample):
// in graphHelper.js
function postSendMail(accessToken, message, callback) {
request
.post('https://graph.microsoft.com/beta/me/sendMail')
//.post('https://graph.microsoft.com/beta/me/sendMail?scope=Mail.Send') // nope
.send(message)
.set('Authorization', 'Bearer ' + accessToken)
.set('Content-Type', 'application/json')
.set('Content-Length', message.length)
.set('scope', 'Mail.Send') // nope
.end((err, res) => {
callback(err, res);
});
}
describe('Integration', function () { // mocha
var accessToken;
var scope;
const config = getConfig();
// My account variables in testConfig.json file
function getConfig() {
var configFilePath = path.join(__dirname, 'testConfig.json');
return JSON.parse(fs.readFileSync(configFilePath, { encoding: 'utf8' }));
}
function getAccessToken(done) {
var postData = querystring.stringify(
{
grant_type: 'password',
//grant_type: 'client_id', // not supported
//grant_type: 'authorization_code', // This assumes you've requested an auth code.
resource: 'https://graph.microsoft.com/',
scope: 'Mail.Send',
client_id: config.test_client_id_v2,
client_secret: config.test_client_secret_v2,
username: config.test_username,
password: config.test_password
}
);
var postOptions = {
host: 'login.microsoftonline.com',
port: 443,
path: '/common/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
var postRequest = https.request(postOptions, function (res) {
var data = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
const response = JSON.parse(data);
accessToken = response.access_token;
scope = response.scope;
done();
});
});
postRequest.on('error', function (e) {
console.log('Error: ' + e.message);
done(e);
});
postRequest.write(postData);
postRequest.end();
}
before( // eslint-disable-line no-undef
function (done) {
getAccessToken(done);
}
);
it('Checking that the sample can send an email',
function (done) {
var postBody = emailer.generateMailBody(config.test_name, config.test_username);
graphHelper.postSendMail(
accessToken, scope,
JSON.stringify(postBody),
function (error) {
assert(error === null, `The sample failed to send an email: ${error}`);
done();
});
}
);
});
I have the following API call in my Reactjs app:
static getAllSkills(title_id) {
const request = new Request(`http://localhost:4300/api/v1/job_title_skills`, {
method: 'GET',
headers: new Headers({
'Content-Type': 'application/json'
}),
body: JSON.stringify({title_id: title_id})
});
return fetch(request).then(response => {
return response.json();
}).catch(error => {
return error;
});
}
Which points to a Rails endpoint which expects the param title_id like so:
def index
#skills = Skill.where(id: params[:title_id])
....
end
The controller is expecting a GET request however with the above, I'm getting the following JS console error:
Uncaught TypeError: Failed to construct 'Request': Request with GET/HEAD method cannot have body.
What is the right way to construct the Request and pass the param to the API?
I think the url in your api is waiting for the title_id maybe like:
api/v1/job_title_skills/:title_id
So you can append it in your url when you make the request:
static getAllSkills(title_id) {
const request = new Request(`http://localhost:4300/api/v1/job_title_skills/${title_id}`, {
headers: new Headers({
'Content-Type': 'application/json'
})
});
return fetch(request).then(response => {
return response.json();
}).catch(error => {
return error;
});
}
Searching for suggestions on handling errors in an Ember test? Found a closed issue from last year, Allowing rejected promises in tests, which indicated that rejections cannot be conveniently handled. Is this still the case?
Right now, in our application, we are using ajax errors to return an unauthorized error if the user is logged out of our main Rails application.
Route
import Ember from 'ember';
import {isUnauthorizedError, isForbiddenError} from 'ember-ajax/errors';
export default Ember.Route.extend({
userService: Ember.inject.service('user'),
activate: function(){
this.get('userService').facility().then(
(data) => {
this.get('controller').set('facility', data.data);
}, (response) => {
if (isUnauthorizedError(response)) {
this.transitionTo('report.failure.401');
} else if (isForbiddenError(response)) {
this.transitionTo('report.failure.403');
} else {
}
}
),
Acceptance Test
test('generates 401 error', function(assert) {
visit('/reporting');
httpStubs.stubUser(server, {}, 401);
httpStubs.stubFacility(server, {});
httpStubs.stubReport(server, '/api/reports/summary.json', []);
click('button.btn-filter')
andThen(function(){
assert.equal(currentURL(), '/users/login');
});
Report Stub
stubReport(server, url, data, status) {
let statusCode = (status) ? status : 200;
server.get(url, function() {
return [
statusCode,
{'Content-Type': 'application/json'},
JSON.stringify(data)
];
});
}