I am using Nightwatch and was hoping to monitor the http requests that are being generated by my nightwatch steps. Is there a way to listen to the requests that are sent and the responses received. I dont need to modify them.
Thanks
Matt
Yes there is a way.
In order to monitor the HTTP requests:
It's basically will monitor when user click on event that send a
request to the server such as: submit button in login page - that send userName & password.
First install npm i nightwatch-xhr
after that you can make a function like that:
module.exports = {
tags: ["test"],
"test": function (browser) {
browser
.windowMaximize()
.url("some url")
.insertValue("namevalue")
.insertValue("passwordValue")
//then write something like that
.waitForXHR(
"",
1000,
function browserTrigger() {
browser.click("submit button")
},
function assertValues(xhr) {
console.log(xhr)
}
);
}
}
It will catch the request data that send to the server.
Related
I need to test some pages on a project and this project do some APIs call to external services.
I need to make sure that these calls are made and check if my page change accordingly to the response.
This is my test:
describe('A logged in user', () =>{
it('can see his subscriptions', () => {
...... some checks .......
cy.intercept('https://example.com/api/v2/user-panel/get-subscription').as('userSubscription');
cy.wait('#userSubscription', { timeout: 35000 }).then(() => {
cy.contains('some text');
});
});
});
When I run the code seems that it can't se the API call but the page content change correctly.
This is the cypress response:
Timed out retrying after 35000ms: cy.wait() timed out waiting 35000ms
for the 1st request to the route: userSubscription. No request ever
occurred.
I tried to increase the timeout, event if the page loads in 1 second, but the result is the same.
There is something am I missing?
Doing the cy.wait() right after the cy.intercept() is not going to work.
Whatever triggers the API calls (a cy.visit() or a .click()) must occur after the intercept has been set up, and it therefore is ready to catch the API call.
From the Network Requests docs
cy.intercept('/activities/*', { fixture: 'activities' }).as('getActivities')
cy.intercept('/messages/*', { fixture: 'messages' }).as('getMessages')
// visit the dashboard, which should make requests that match
// the two routes above
cy.visit('http://localhost:8888/dashboard')
// pass an array of Route Aliases that forces Cypress to wait
// until it sees a response for each request that matches
// each of these aliases
cy.wait(['#getActivities', '#getMessages'])
// these commands will not run until the wait command resolves above
cy.get('h1').should('contain', 'Dashboard')
I'm having a problem with stubbing a simple request to an API using the cypress' cy.server() and cy.route().
Here's the failing test:
it.only("should show an error message for server errors", () => {
const name = "It doesnt matter";
const email = "takenemail#yopmail.com";
const pass = "123123";
// run the server and define the stubbed route
cy.server();
cy.route(
"POST",
`${serverBaseUrl}/auth/register`,
"fixture:register-fail.json"
).as("postRegister");
// fill in the registration form and hit submit
cy.visit("/auth/register");
cy.get(selectors.registerForm.name).type(name);
cy.get(selectors.registerForm.email).type(email);
cy.get(selectors.registerForm.password).type(pass);
cy.get(selectors.registerForm.registerButton).click();
// intercept the request and mock it
cy.wait("#postRegister"); // this fails.
cy.get(selectors.registerForm.genericErrors).contains(
"This email has already been taken"
);
});
and the error:
cy.wait() timed out waiting 5000ms for the 1st request to the route: postRegister. No request ever occurred.
Note: even though it says that No request ever occurred. I can still see the request being send and a response received in the console's Network tab (which means the stub has been bypassed and a regular request's been made).
Any ideas what's happening?
Thanks in advance.
Ok, seems like i have found the problem.
It turns out that using the fetch API is not supported by cypress.
The workaround - using whatwg-fetch, which is basically a polyfill for the fetch api, working with XHR behind the scenes.
Install the whatwg-fetch package: npm install whatwg-fetch --save
Import it in your project: import "whatwg-fetch";
Last, but very important - remove the fetch object from the window before every page load in the cypress environment like this:
// you can define this in the commands file for example...
Cypress.on("window:before:load", (win) => delete win.fetch);
or an alternative, per-visit approach:
it("some test", () => {
cy.visit("/url", {
onBeforeLoad: win => delete win.fetch // <---
});
// ...the rest of the test
});
Doing this will kick-in the polyfill and the stubbing should be working properly after this intervention.
On Slack's incoming webhook documentation, they mention including the thread_ts in the request body to start a thread.
{
"text": "Hello, world.",
"thread_ts": "12345.6789"
}
When I make the POST request to my incoming webhook url, the response body does not include the thread_ts. I was expecting the thread_ts to be in the response body, but the response body just says ok and does not include any json.
Is it possible to get the thread_ts without another app or authentication token? Do I have to use another Slack API? I only have the incoming webhook configured right now.
As a side note, if this is easier to do with Slack's new Block Kit API, that would work as well.
To take full control of all messaging features of Slack including threads you want to use the API.
When posting messages with chat.postMessage you get the thread_ts value and can start creating threads.
Also check out this official documentation on threads. It clears up a lot.
I am not an export on the new blocks yet, but as far as I understand it replaced the attachments and provides a more flexible way for message layouts. It does however not change the way threading works.
from slack_sdk import WebClient
slack_client = WebClient(token='token_value')
response = slack_client.chat_postMessage(channel=receiver, text=message)
print(response.data)
thread_ts = response.data['ts']
In case of Bolt api (js) you can check ts value from callback arguments.
app.message(
"link please",
async ({ message, say }) => { // You can also get ts from `payload`
console.log(message);
await say({
text: "you can check this link",
thread_ts: message.ts, // you can get ts from message
});
});
message content:
{
client_msg_id: 'xxxxx',
type: 'message',
text: 'xxxx',
user: 'UxxR',
ts: '1650249299.335499',
team: 'xxxx',
blocks: [ { type: 'rich_text', block_id: 'adOR', elements: [Array] } ],
thread_ts: '1650249116.347219',
parent_user_id: 'UxxxxxR',
channel: 'C01TNEN8SSK',
event_ts: '1650249299.335499',
channel_type: 'group'
}
I am using a Slack webhook to process incoming SMS messages from Twilio. However, the way I have it set up, It seems that Twilio is expecting the web server (slack) to respond to it. This causes errors to be generated in Twilio, and I obviously don't want errors because I'll be getting emails.
I am using the twilio-ruby gem in Ruby to send out the SMS messages, and using the slack-ruby-client to monitor incoming messages from Slack.
How do I stop Twilio from trying to expect a response from the web server when it POSTS to the Slack webhook? Is that even possible or do I have this all configured incorrectly?
EDIT
Here's the function that I have which sends the forwarded SMS to Slack:
const https = require("https");
// Make sure to declare SLACK_WEBHOOK_PATH in your Environment
// variables at
// https://www.twilio.com/console/runtime/functions/configure
exports.handler = (context, event, callback) => {
// Extract the bits of the message we want
const { To, From, Body } = event;
// Construct a payload for slack's incoming webhooks
const slackBody = JSON.stringify({
text: `!asi SMS\nFrom: ${From}\nMessage: ${Body}`
});
// Form our request specification
const options = {
host: "hooks.slack.com",
port: 443,
path: context.SLACK_WEBHOOK_PATH,
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": slackBody.length
}
};
// send the request
const post = https.request(options, res => {
// only respond once we're done, or Twilio's functions
// may kill our execution before we finish.
res.on("end", () => {
// respond with an empty message
callback(null, new Twilio.twiml.MessagingResponse());
});
});
post.write(slackBody);
post.end();
};
Twilio developer evangelist here.
Twilio is always going to expect at least a 200 response or will timeout at 15 seconds for incoming message webhooks.
You could avoid the error messages by using something in between Twilio and Slack, like Zapier (example in this blog post) or using a Twilio Function (as described here) or with Twilio Studio (from the documentation here).
Hope one of those ideas helps!
Update
Further to my earlier answer, and given the code you used to make the call, I have an update.
When making a request using Node's built in https module you will not get the end event until you have read the data. This is what is causing the timeout between Twilio and the Twilio Function, you are never responding to it because you don't consume the data from the request.
In a quick test I found that just listening for the data event meant that the end event did fire. So update your function to:
const post = https.request(options, res => {
// only respond once we're done, or Twilio's functions
// may kill our execution before we finish.
res.on("data", () => {});
res.on("end", () => {
// respond with an empty message
callback(null, new Twilio.twiml.MessagingResponse());
});
});
And it should work.
I am working on an application where different ajax requests fires depending upon different actions.
For example, there is a chat window having send button. When i click on that button an empty message is sent with ajax, successfully. It work nice. But when I hit the send button too many times, at start some requests respond 200 (ok) but then it respond 500 (internal server error). Due to this the other requests that are going continuously like updateLastActivity also disturb.
The preview of the error in developer's tool is:
Whoops like something went wrong.
Note: When I make this chat system in core PHP, it work fine. There is no internal server error when I send too may requests.
Here is the code I am using
//the following code is used to send the message
$(document).on('click','.send_message_bt',function(event){
event.preventDefault();
var id=$(this).data('id');
var name=$(this).data('name');
var message=$("#message_field-"+id).val();
$.ajax({
//headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
headers: { 'X-CSRF-TOKEN': {!! json_encode(csrf_token()) !!} },
url:'{{route('user.sendmessage')}}',
type:'POST',
data:{
id:id,
message:message
},
success:function(data,status){
//clear the message field value
$("#message_field-"+id).val('');
//update the chat history
fetchChatHistory(id,name);
},
error:function(response){
if(response.status==401){
alert('You are not logged in!');
window.location=window.location.href;
}
}
});
});
here is the back end code
public function sendMessage(Request $request){
$message=new Userchatmessage();
$message->message=$request->message;
$message->sender_id=Auth::user()->id;
$message->receiver_id=$request->id;
$message->save();
return response('success');
}
How to fix this issue.
I guess it's not a problem with Laravel or anything, but with your browser. Each browser has a maximum amount of simultaneous connections it will open for a certain domain.
Read more about this problem here and here.
If you want to make a realtime chat application, consider using something like NodeJS and Socket.io.
Async and await can help. Let an async function
async function doAjax(){
await runFirstAjaxCall();
await runAfterFirstAjaxCallSuccess();
....
....
}
doAjax();