I need a clarification about the Codename One UITimer.
For example, if I want to execute the same code every two seconds, a code like UITimer.timer(2000, true, () -> { do something; }); works until the user stays in the current Form? Is that right?
If I want to execute the same code every two seconds regardless the shown Form, have I to use something different from UITimer, like a custom separate thread? For example the following code?
Form hi = new Form("Hi World", BoxLayout.y());
hi.add(new Label("Hi World"));
hi.show();
EasyThread.start("MyTimer").run(() -> {
boolean executeMe = true;
while (executeMe) {
Log.p("Do something every two seconds...");
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Log.p("Stopping the EasyThread \"MyTimer\" because an exception");
Log.e(ex);
executeMe = false;
}
}
});
Moreover, if I execute this example code, the first logged line is:
[MyTimer] 0:0:0,59 - Codename One revisions: 8b451ecb7bfbe60baf91006441e7d7d9c46afe09
Why is that line logged by my custom thread instead of by the EDT?
Yes, UITimer is an animation associated with the current Form. It doesn't draw anything but uses the builtin animation mechanism which runs on the EDT. Notice that if you leave a form and return to it the timer will continue e.g.:
Opened form at 0 time and set a timer for 15 seconds
Went to different form at 7 seconds
Returned to original after 30 seconds - the timer will fire immediately on return
You can also use a regular Timer or Thread. However, for your specific code EasyThread doesn't provide a benefit over a regular thread since it runs in an infinite loop. The benefit of EasyThread is in it's job processing ability.
Notice that you would need to use callSerially to return to the EDT when working with such timers/threads.
Related
I know about the three different types of waiting you can use in Selenium. I know why Thread.Sleep and ImplicitWait are never a good choice. So I'm always using ExplicitWaits, for instance to wait till a button is clickable. However, from time to time one or two tests in a collection of hundred tests fails because the Explictwait seems to fail.
I read the very interesting article: https://bocoup.com/weblog/a-day-at-the-races
about the reason why tests can fail from time to time and Explicit wait as the solution for this intermittent failures. This made me even more convinced about using ExplictWaits.
So I wonder is there anybody who knows situations were an Explicitwait is not doing the right job.
This is my C# code for waiting till a Webelement is clickable:
public static Boolean waitElementToBeClickable(IWebDriver driver, int seconds, IWebElement webelement)
{
Boolean clickable = true;
try
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(seconds));
wait.Until(ExpectedConditions.ElementToBeClickable(webelement));
}
catch
{
clickable = false;
}
return clickable;
}
In one of the application workflows I have more than 10 pages to navigate.
I have to keep clicking on the 'Next' button continuously - it makes an AJAX call to re-load new content and 'Next' button will also be reloaded.
The number of pages to navigate is not always 10. It might be anything from 10-100.
My test will be complete whenever there is a webelement found with the id 'testcomplete'.
So Currently i use ExpectedConditions()
WebDriverWait wait = new WebDriverWait(driver, 30);
//Keep clicking next
while(isNextPresent()){
NextButton.click();
}
//testcomplete reached here
System.out.println("test complete");
private boolean isNextPresent(){
try{
WebElement element = wait.until(ExpectedConditions.visibilityOf(NextButton));
return true;
}catch(Exception e){
//
}
return false;
}
Currently my code works fine. But i am trying to improve it. I hate the unnecessary wait of 30 seconds when the element with the id 'testcomplete' is present. Because that time 'NextButton' will not be present.
How can I improve this isNextPresent function? Ie, to return false immediately when there is 'testcomplete' instead of waiting for 30 seconds?
Note: I have tagged protractor as well because I also have a similar requirement in protractor.
You can combine the conditions of both elements and take an action depending on the fact which one first returns true for 'visibilityOf(myElement)'. Maybe something like this in pseudo (sorry, no IDE around):
loop(i < 30){
// wait NextBtn for 1 sec, if true click and break
// wait TestCopmlete for 1 sec
}
Use EC.or(), a la:
wait.until(ExpectedConditions.or(
ExpectedConditions.visibilityOf(NextButton),
ExpectedConditions.visibilityOf(element(by.id('testcomplete')))
));
Then after this comes back, expect the desired state:
expect(NextButton.isDisplayed()).toBeTruthy();
I'm using Behat 3 and PhantomJS 2. Currently I have a scenario defined as such:
#javascript
Scenario: I visit the blog through the Blog & Events menu.
Given I am an anonymous user
And I am on the homepage
And I follow "Link Text"
Then I should be on "/path-to-page"
When I run this with Goutte it's fine. When I run this with vanilla Selenium, it's fine (it launches a browser I can see). However, when I configure Selenium to point the webdriver host to PhantomJS, it explodes on Then I should be on "/path-to-page" claiming it's still on /.
If I add the following wait step:
#javascript
Scenario: I visit the blog through the Blog & Events menu.
Given I am an anonymous user
And I am on the homepage
And I follow "Link Text"
And I wait 4 seconds
Then I should be on "/path-to-page"
Then my scenario passes in the green, all good.
Is there a way to get PhantomJS to wait for the page to load before checking the current path? I don't want to depend on arbitrary timeouts. I need a headless solution and PhantomJS seems to be pretty well supported, but if I can't do something as simple as clicking a link and verifying the page that was loaded without adding random waiting steps everywhere, I might need to re-evaluate my decision.
Try using this implicit wait in your feature context. In my experience it has helped.
/**
* #BeforeStep
*/
public function implicitlyWait($event)
{
// Set up implicit timeouts
$driver = $this->getSession()->getDriver()->getWebDriverSession();
$driver->timeouts()->implicit_wait(array("ms" => 10000));
}
I was having the same issue, and doing something like this fails because its using the state of the current url:
$this->getSession()->wait(10000, "document.readyState === 'complete'");
So my workaround for this was adding a variable to the page every time a step is done. When I link is clicked, the variable will no long exist, this will guarantee that am working with a different page.
/**
* #AfterStep
*/
public function setStepStatus()
{
$this->getSession()->evaluateScript('window.behatStepHasCompleted = true;');
}
/**
* #When /^(?:|I )wait for the page to be loaded$/
*/
public function waitForThePageToBeLoaded()
{
$this->getSession()->wait(10000, "!window.behatStepHasCompleted && document.readyState === 'complete'");
}
You can always make use of a closure function to encapsule your steps, just as mentioned in the docs. Through it, you can get your steps to run when they're ready. Let's implement a spinner function:
public function spinner($closure, $secs) {
for ($i = 0; $i <= $secs; $i++) {
try {
$closure();
return;
}
catch (Exception $e) {
if ($i == $secs) {
throw $e;
}
}
sleep(1);
}
}
What we're doing here is wait for a number of seconds for the closure function to run successfully. When the time's run out, throw an exception, for we want to know when something's not behaving correctly.
Now let's wrap your function to assert you're in the right page within the spinner:
public function iShouldBeOnPage($wantedUrl) {
$this->spinner(function() use($wantedUrl) {
$currentUrl = $this->getSession()->getCurrentUrl();
if ($currentUrl == $wantedUrl) {
return;
}
else {
throw new Exception("url is $currentUrl, not $wantedUrl");
}
}, 30);
What we're doing here is wait up to 30 seconds to be on the url we want to be after clicking the button. It will not wait for 30 secs, but for as many secs we need until current url is the url we need to be at. Applying it in your function within the *Context.php will result in it being applied in every step you call it within your Gherkin files.
I thought I knew what causes this exception until I wrote this:
var menu = ViewConfigHelper.CreateObjectFromResource<Menu>(config, baseURI);
if (!menu.Dispatcher.CheckAccess())
{
throw new ArgumentException("Somethign wrong");
}
if (!LayoutRoot.Dispatcher.CheckAccess())
{
throw new ArgumentException("SOmethign wrong");
}
// exception throw here
LayoutRoot.Children.Insert(0, menu);
First line creates a Menu control from an embedded XAML file. Both CheckAccess calls return true. However, when last line is executed, an exception is thrown with the message "Caling thread cannot access object because differrent thread owns it." The code above is being executed within a method called immediately after InitializeComponent() that created LayoutRoot, on the same thread, I believe.
Someone please enlighten me. I am trying to create a multiple UI thread WPF app.
You are using CheckAccess() in reverse. You want to lose the ! signs before each check. See the example bit of code on the CheckAccess() MSDN page.
In the Winforms world you'd do a InvokeRequired() which is now the same thing as a !CheckAccess(). In your case because both values are returning true, and you are inverting them, neither if block is hit.
To expand a bit... in the Winforms world, the normal patter was:
if(InvokeRequired)
{
Invoke(...);
}
else
{
//do work
}
(or sometimes a return after invoke, if it was invoking the same method).
In WPF, CheckAccess() is similar to, but not identical to InvokeRequired... there for a pattern more along the lines of:
if (someUiControl.Dispatcher.CheckAccess())
{
//Doing an update from this thread is safe, so we can do so here.
}
else
{
// This thread does not have access to the UI thread.
// Call the update thread via a Dispatcher.BeginInvoke() call.
}
The key difference between is that InvokeRequired() returning true meant it was UNSAFE to do the update in the current thread... while a true from CheckAccess() means it is SAFE.
I am creating a quick'n'dirty utility that will enable editing of data read sequentially from a set of files. Here's a very simplified explanation of what will happen in a single iteration of a loop:
Read a line from the input stream
Parse it and use the parsed results to populate form controls
Allow user editing and await a confirmation button click
Retrieve the updated form control values and write to the output stream
What I can't figure out is how to integrate the processing loop with the event-driven UI. For example, how do I suspend operation of the loop while waiting for user input.
I understand that this is possible by launching the loop operation on its own thread and writing code to manage its interaction with the UI thread, but I am wondering if there is a simpler approach that works out of the box.
Thanks for any ideas you may be able to offer.
Tim
I can think of 2 approaches to do that:
The easiest is probably to use a modal dialog: when your worker thread needs input from the user, display a dialog, which is a blocking operation. Something like that:
// Worker thread loop
while(...)
{
...
// prompt user for data (invoke synchronously on UI thread)
UserData data = (UserData)window.Invoke(PromptUserData);
...
}
...
UserData PromptUserData()
{
UserInputDialog dlg = new UserInputDialog();
dlg.ShowDialog();
return dlg.UserData;
}
The other option, if you don't want to use a modal dialog, is to use a wait handle to synchronize the worker thread and the UI:
private readonly AutoResetWaitHandle _userInputWaitHandle = new AutoResetWaitHandle(false);
...
// Worker thread loop
while(...)
{
...
// Setup the UI to allow user input
window.Invoke(SetupUIForInput);
// Wait for the input to be validated
_userInputWaitHandle.WaitOne();
...
}
...
void SetupUIForInput()
{
// Enable the UI
inputForm.Enabled = true;
// Whatever else you need to do...
...
}
void buttonOK_Click(object sender, EventArgs e)
{
// Signal the worker thread to continue
_userInputWaitHandle.Set();
}
You wouldn't really implement a loop in the narrow sense.
You would do something like this (pseudo code):
OnStartOperationButtonClick()
{
if(!ReadLine())
return;
ParseLineAndPopulateControls();
ShowEditingControls();
}
OnConfirmationButtonClick()
{
GetControlValuesAndWriteToOutputStream();
if(!ReadLine())
{
HideEditingControls();
return;
}
ParseLineAndPopulateControls();
}
No need for a separate thread, given that reading and parsing the line doesn't take long.