Im trying to check the content of a toast message using playwright but cant find a suitable way to acheive this.
The playwright documentation lists a suitable way to handle alert messages with which I have been able to do things like retrieve the text content from an alert before dismissing it. For example:
Page.Dialog += (_, dialog) =>
{
alertMessage = dialog.Message;
Console.WriteLine(alertMessage);
dialog.AcceptAsync();
};
prints the alert text content prior to accepting the dialog. This can be extended to perform checks such as asserts etc
I've tried using the same approach when trying to handle the toast message but this doesn't work for me, presumably due to different nature of the toast message.
Has anyone successfully managed to interrogate toast messages using playwright?
There is no official documentation from playwright on how to handle toast messages.
Handling Toast Messages in Automation:
Toast messages are normal html elements within the page(not in alert) however they are special in sense as they appear for a very short time and then disappear so we need to write automation code and handle accordingly. Example Below:
async clickSave() {
await Promise.all([
this.page.waitForSelector(loadPanel),
this.page.click(btn_Save),
this.page.waitForSelector('div[class*="ajs-success"]',{state: 'attached'}) //Toast Success message on save successfully
]);
}
Related
I am using the Bot Framework to build a speech enabled Bot which handles various events, and triggers a Dialog based on the event. The Bot is connected using WebChat as the interface. As this is mostly a proactive scenario, there is no prior input from the user. As a result, even though the dialog is triggered, there is no output speech, since the speech is activated only if the previous interaction was via Speech. To enable output speech, I right now have to explicitly set the ChannelData of every outgoing activity with 'speak' property as true using activity.ChannelData = new {speak = true};, which WebChat understands , and voices out the message associated with the Activity.
Is there a more efficient way to do this, by setting this property in a common location, so that all outgoing activities by default will be spoken out?
To run any code at all whenever the turn context sends an activity, you can use TurnContext.OnSendActivities:
turnContext.OnSendActivities(async (tc, activities, next) =>
{
activities.ForEach(activity => activity.ChannelData = new { speak = true });
return await next().ConfigureAwait(false);
});
This is often done with middleware, but you could possibly choose to do it at the start of your main bot logic.
I am using the following libraries to connect a bot to a Google Pub/Sub endpoint to perform a simple reply to a card click event.
Google.Apis.HangoutsChat.v1 1.34.0.1233
Google.Cloud.PubSub.V1 1.0.0-beta18
When I construct my card, everything looks normal in the UI, including the button that is supposed to raise the event.
The topic and subscription contain the default settings, following the guide here
I found the following information from the Google documentation about retries here
Responding synchronously
A bot can respond to an event synchronously by returning a
JSON-formatted message payload in the HTTP response. The deadline for
a synchronous response is 30 seconds.
A synchronous response from a bot is always posted in the thread that
generated the event to the bot.
After clicking the button, my subscriber receives 3 duplicate events. The events have the correct response with all of the right metadata, but are exact duplicates of each other, including the id of the message itself.
I don't feel there is a necessarily large delay in the response of the bot (it should happen in <1 second for this test), so I am not sure why these messages are being duplicated.
I've also tried setting the thread id for the card when responding (via the Thread property itself, or the ThreadKey property), but I always seem to get a new thread id when I post a message.
var cardMessage = MessageSender.Spaces.Messages.Create(new Message()
{
Space = new Space()
{
Name = inReplyToThisMessage.Space.Name
},
Thread = new Thread()
{
Name = inReplyToThisMessage.Thread.Name
},
Cards = new List<Card>()
{
card
},
}, inReplyToThisMessage.Space.Name);
var sendCardResult = await cardMessage.ExecuteAsync().ConfigureAwait(false);
//Thread id of sendCardResult does not match inReplyToThisMessage.Thread.Name no matter what
Interestingly enough, trying to create a new message in response to the click event causes the bot to display a "Unable to connect to bot. Try again later", but displays 3 new messages. Also, when specifying an arbitrary thread key, this key is never echoed back in the bot's response.
Make sure you are returning the main event method properly. What looks to be happening is that you are making an asynchronous call to the chat, but then the chat is looking for a response from the actual event method itself. Google will traditionally try three times before giving up (even if it doesn't take thirty seconds)
If you are indeed returning the event call correctly after you made your api request, then there is something in your code that is causing the Google Bot to think it is not getting a response, so it tries three times. Since the issue could be multi-faceted I would need to look at how you are accepting and returning the click response.
This bug has finally been fixed by Google.
TL;DR: the bot takes 2-9 seconds to send any message to the user, even if I send the message from the very first line in MessagesController.cs.
I have used the Bot Framework to create a couple of bots for Facebook Messenger and I noticed that one of them is significantly slower than the other.
Both bots have the code below as the very first lines in the MessagesController.cs. This is supposed to send the Typing indicator to the user.
One bot consistently takes 2 seconds to show this typing indicator to the user on Facebook, while the other takes 9 seconds.
Activity typing = activity.CreateReply(null);
typing.ServiceUrl = activity.ServiceUrl;
typing.Type = ActivityTypes.Typing;
ConnectorClient connector = new ConnectorClient(new Uri(typing.ServiceUrl));
await connector.Conversations.SendToConversationAsync(typing);
The second bot indeed does much more work (calling various web APIs), but since these lines are the very first in the controller, I expect the typing indicator to be sent to the user immediately, after which the bot can continue doing its work.
However, it seems that the messages (including the typing indicator) are not sent until the bot completes its work.
Is there a way to "flush" the messages to the user to have a typing indicator sent immediately, or am I encountering some other issue?
Update: I've tried the ConnectorClient.Dispose() method but it doesn't seem to help make it any faster to send messages.
I am not sure what you mean by "flushing" the messages to the user but your bot should show the typing indicator immediately until you type a message and there is some process in the background. To avoid processing information until the user types a message you can use the ActivityTypes like this:
if (activity.Type == ActivityTypes.Message)
{
Activity typing = activity.CreateReply(null);
typing.ServiceUrl = activity.ServiceUrl;
typing.Type = ActivityTypes.Typing;
ConnectorClient connector = new ConnectorClient(new Uri(typing.ServiceUrl));
await connector.Conversations.SendToConversationAsync(typing);
}
else
{
HandleSystemMessage(activity);
}
...
However, it makes sense that the user cannot type anything until the application has already given a answer back to the previous question.
This may seem like an odd question, but is there a way to send a local toast notification from a Windows 8 Store App to the machine--and NOT show it on the screen? I have a background task that needs to send a sync request to the UI thread. I have been searching for the better part of 8 hours trying to get different methods to work--and it comes down to this will work for me, but I don't want the request text to show up on the screen when I call it.
I should also add that Toast Notifications WILL be used in the app, so I can't simply turn it off globally, I need only the ones I specify to not show up, to be hidden. Is this possible?
Ideally, I would rather do a Raw Notification, but I can't figure out how to do a local Raw Notification (of if its even possible to simulate it without hitting my API.).
EDIT: Root Problem
My background task is doing work behind the scenes every 15 minutes--to basically send a sync request to the main app. The OnPushNotificationReceived, should capture this and perform a full sync of all data I need: Such as GPS coordinates, checking if "ToDoItems" are nearing due dates and need to be escalated in priority, etc. Among other things, such as checking if there are any documents on the local file system that have been marked as complete and need to be uploaded to Azure file storage, etc.
The answer might be in the OnPushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs args)
args.Cancel = true
From MSDN: https://msdn.microsoft.com/en-us/library/br241295
Cancel:
Read/write Gets or sets whether Windows should perform its default handling of the notification.
You receive the notification and process it in your OnPushNotificationReceived listener, set the cancel to true and voila!
Basically you already processed the notification, so you cancel the default behaviour that is showing the notification.
EDIT CONTENT:
The Raw Notification basically is an empty envelope where you can put any content in any form you want, could be an object, an image, a dictionary... Basically you decide the content to send and obviously the app must know the datamodel to be able to process it.
To create Notifications easily I recommend you this Nuget Package: https://github.com/WindowsNotifications/NotificationsExtensions/tree/master/Windows%208.1%20RT
Example on how to create a toast notifcation:
var toastNoti = ToastContentFactory.CreateToastText02();
toastNoti.TextHeading.Text = "TEXT IN BOLD";
toastNoti.TextBodyWrap.Text = "TEXT IN NORMAL CASE ";
toastNoti.Launch = "NOTIFICATION ARGUMENTS";
var doc = new XmlDocument();
doc.LoadXml(toastNoti.ToString());
var endNotification = new ToastNotification(doc);
endNotification.Tag = "1";
ToastNotificationManager.CreateToastNotifier().Show(endNotification);
Hope this helps. Tell us any result please.
I am running some automation in a C# program (.Net 4.0). There is an issue with a modal dialog where I want to click the message away and continue testing. I have tried a few options (SendKey and using Win32 to send a click event with code modified from here: http://msdn.microsoft.com/en-us/magazine/gg309183.aspx. Neither of these have proved to be reliable enough to be considered effective.
My next approach will be to try calling the EndDialog() function from my C# program and simply sending the enumeration/return code to the message box.
EndDialog(HWND hDlg, INT_PTR nResult) is the call where hDlg is the handle to the message box being closed and nResult is the result of the dialog.
Where I am running into an issue is how to send the desired result. An example would be that the return code IDCANCEL has a value of 2. How exactly do I send this value? What variables or constants would I need to declare? I'm just looking for how to get the proper pointer declared to send the desired result to the function.
Further information on these result values can be found here http://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=VS.85).aspx
just invoke PostMessage. Here is a sample in c/c++:
::PostMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDCANCEL,BN_CLICKED), 0);