Angular Material: How to display one toast after another one is displayed while keeping both on screen? - angular-material

I'm using $mdToast (Angular Material framework) directive to show several status messages in my Angular(-Material) web app.
When the user signs-in, if the login is successful a toast is shown by calling:
$scope.showToastMessage = function() {
var toast = $mdToast.simple()
.content("Login successful);
.action('OK')
.highlightAction(false)
.position($scope.getToastPosition());
$mdToast.show(toast).then(function(toast) {
//...
}
});
};
After login success I need to make another check (e.g. valid session cookie) and show another toast message without overriding the previous one and after the previous one is actually showed.
The issues I get here are:
the second toast is shown before the new one (probably due to $mdTost's async nature)
this second toast is shown for less than one second and then disappears leaving on screen only the first one (basicly the second one is shown first and then hidden when the first one appears)
A solution could be either:
creating the second toast inside then .then callback: this doesn't work either because requires the user interventions to press the "OK" action button
calling $mdToast.updateContent(); (https://material.angularjs.org/#/api/material.components.toast/service/$mdToast) which would overwrite previous toast message (this is not the best solution but would be fine either) but I can't figure out how:
(1) choose a specific toast shown on screen (let's suppose I have several toasts shown by different calls) , and
(2) update the toast message after a delay (let's say 3 seconds) in order to show to make the user undersand that the login was successful but there is some other information.
Any clue?

I was not sure if you wanted to show both toasts at the same time or not. If you wanted to show the sequentially you can put the second call to toast inside of the then because the action (OK) resolves the promise of the first toast. This is what I've tried:
var toast = $mdToast.simple()
.content('top left')
.action('OK')
.highlightAction(false)
.position($scope.getToastPosition());
var toast2 = $mdToast.simple()
.content('Checking some other things')
.highlightAction(false)
.position('top left');
$mdToast.show(toast).then(function() {
$mdToast.show(toast2);
});
See this CodePen.

Related

Appium Touch Actions 'Press' and 'Move To' is not working in iOS chrome app

I am learning mobile automation and I came across a scenario some thing like this
Launch chrome app in iOS
Load https://www.google.com
Hold/Press and pull down banner web element on the web page which will display some overlay with three options 'New tab, Reload & Close tab' (note: overlay will lost on releasing the banner web element)
Tap on the new tab button
So far I have written below script in python
def Test(self, driver_provider):
single_tap = appium.webdriver.common.touch_action.TouchAction(driver_provider.driver)
element = driver_provider.driver.find_element_by_accessibility_id('NTPHomeFakeOmniboxAccessibilityID')
single_tap.tap(element=element).perform()
element.send_keys('https://www.google.com')
single_tap.tap(element=driver_provider.driver.find_element_by_accessibility_id('Go')).perform()
time.sleep(1)
#Press banner and pull down will display the over scroll actions
#Then move to left to tap on the add button
banner_element = driver_provider.driver.find_element_by_accessibility_id('banner')
screen_size = driver_provider.driver.get_window_size()
height = screen_size.get('height')
width = screen_size.get('width')
single_tap.press(banner_element, x=banner_element.size.get(
'width')/2, y=banner_element.size.get('height')/2).wait(1).move_to(banner_element,
x=width/2, y=height/2).wait(0.5).move_to(banner_element, x=0, y=height/2).release().perform()
for some reason press and move_to actions are not happening and there is no error returned as well, I am not clear what went wrong here. Please share your view on what went wrong thanks.
it's failing to perform press and move to because of wait value is very small. When I use the wait(500) then the press and move to is happening.
single_tap.press(banner_element, x=banner_element.size.get(
'width')/2, y=banner_element.size.get('height')/2).wait(500).move_to(banner_element,
x=width/2, y=height/2).wait(500).move_to(banner_element, x=0, y=height/2).wait(500).release().perform()

Layout changes do not apply in tests

I have a button that allows to hide itself and another widget when pressed. When it is hidden, a new button appears on the screen which can undo (show) the previous button and widget again.
I'm pretty sure my implementation for this works because I've tested it on multiple devices without any problems, but whenever I try to write a formal test for it, something goes wrong. I'm using the following code to test my widget:
await tester.tap(find.widgetWithText(GestureDetector, "HIDE"));
expect(testContainerState.ifContainerWithOptionsIsDisplayed, false);
print(find.byType(GestureDetector));
await tester.tap(find.widgetWithText(GestureDetector, "SHOW"));
expect(testContainerState.ifContainerWithOptionsIsDisplayed, true);
The first two lines are there to tap the button and check whether ifContainerWithOptionsIsDisplayed changed. In my implementation, this is done in a setState method and should repaint to hide the widget and button and show the new button.
In the third line, I check how many GestureDetectors I can still find after what should be a repaint. The output of that print statement still shows me that all of the GestureDetectors of the widget that should now be hidden are still being found.
In the 4th line, I try to find my SHOW button that should now be visible because of the repaint. But no element is found.
Again, I'm pretty sure the code for my widgets are correct because I've tested this test case manually without any issues. Perhaps I'm missing some knowledge about Flutter tests. Could someone please fill me in?
await tester.pump();
or just
tester.pump();
should do that
See also
https://docs.flutter.io/flutter/flutter_test/WidgetTester/pump.html
https://docs.flutter.io/flutter/flutter_test/WidgetTester/pumpAndSettle.html
https://flutter.institute/flutter-and-widget-tests/

Appium: How to wait for new element with same name as visible one to appear on screen?

We're using Appium with iOS Simulator and test functions written in Java.
We have an iOS App with screen 1 containing a UICollection view, and tell Appium to click on one of its elements.
This opens screen 2 (and the scrolling animation takes about 500 ms), which also contains an UICollection view. I want to find out the size of the UICollection view of the second screen with Appium.
The problem is that Appium is too fast and executes the findElements() method directly after the click, which causes it to find the UICollection view of the first screen.
clickOnElementOnFirstScreen();
webDriver.findElements( By.className( "UIACollectionCell" ) ).size();
// is supposed to find the UICollection view on the second screen,
// but actually finds the UICollection view on the first screen
Appium provides several waiting functions. However as far as I can see all of them are intended to be used in this fashion:
"wait until element at location X / with name X becomes visible"
If I try to use these waiting functions, they don't wait at all because they immediately find the UICollection view of the first screen, which has the same location and name as the one on the second screen.
The only solution I have found is to use Thread.sleep:
Thread.sleep(1000);
webDriver.findElements( By.className( "UIACollectionCell" ) ).size();
But we don't want to use Thread.sleep in code that will run on the client's server on hundreds of tests.
We might be able to modify the App and enter metadata into the views so that Appium is able to distinguish them, but this situation occurs in several places and the App is being programmed by the client, so we want to avoid this too.
What is a simple and safe way to wait for the new screen to appear, without modifying the code of the iOS App?
I have found only dirty workaround for this issue.
static waitFor(Duration duration) {
try {
def WebDriverWait wait = new WebDriverWait(mobileDriver, duration.standardSeconds)
wait.until(visibilityOfElementLocated(By.xpath("//Fail")))
//Wait until false case is visible to ensure proper timeout
} catch (Exception e) {
}
}
Another workaround/solution that has been posted on the Appium forums is:
First search for some other element that distinguishes the 2. screen from the 1. screen; once that is visible, it's safe to search for the originally desired element.

Showmodaldialog help button in title bar

I have an HTA which opens a showmodaldialog and this JavaScript code in the dialog page:
function helpButton(){
document.body.style.curosor = "help";
my_div.onclick = function(){alert("Help for the div is displayed here")}
}
I want a help button in the title bar of the showmodaldialog, like on the picture below:
(don't mind about the fact that the picture's in French, it's my computer's language)
When I push on that help button, I want it to execute the helpButton() function.
There was showModalDialog('path', 'arg', 'help:yes'); and you could attach an onhelp handler within the opened dialog's window. However, this dialog property is obsoleted - since IE9, if I'd recall correctly - and can't be returned by downgrading the app using X-UA when running a HTA with a newer IE.
You still can set onhelp, and call it by hitting F1:
window.onhelp = function () {
alert('Help is asked.');
};

Caliburn micro ShowDialog wont appear a second time

I am working on an application that has a splash screen and then a login screen before it pulls up the application. I am using Caliburn Micro to tie everything together but for some reason I am only able to get the Splash Screen to appear. Once the splash screen finishes loading, I call the secondWindow.ShowDialog(LogOnVM) and nothing happens. If I comment out the splash screen code, the the login screen does appear just fine. They just don't appear one after another.
I used Application.Windows.Count after the second ShowDialog gets called and it does show a count of 1. (It is 0 after the first dialog closes) So I know there is a form opening somewhere but I its not visible or something.
I have even tried creating a new instance of WindowManager but that did nothing either.
I have placed:
var cmWindowManager = IoC.Get<IWindowManager>();
var cmSplashScreenViewModel = IoC.Get<SplashScreenViewModel>();
cmWindowManager.ShowDialog(cmSplashScreenViewModel);
var cmLogOnViewModel = IoC.Get<LogOnViewModel>();
var result = cmWindowManager.ShowDialog(cmLogOnViewModel);
Here is how it is being setup. Should I create a second SimpleContainer
protected override void Configure()
{
LogManager.GetLog = x => new DebugLog(x);
sc = new SimpleContainer();
sc.Singleton<IWindowManager, WindowManager>();
sc.Singleton<IEventAggregator, EventAggregator>();
sc.Singleton<IFakeStartupTask, FakeStartupTask>();
sc.PerRequest<SplashScreenViewModel>();
sc.Singleton<IMessageBoxService, MessageBoxService>();
sc.PerRequest<LogOnViewModel>();
}
you need to call TryClose() in your cmSplashScreenViewModel
Below code can show twice the login window (after the 1st login closed)
var login = this.container.GetExportedValue<LoginViewModel>();
var windowManager = IoC.Get<IWindowManager>();
windowManager.ShowDialog(login);
windowManager.ShowDialog(login);

Resources