In my project I use simple JavaFX browser, that works in background and do some stuff without displaying it.
More precisely it submitted some form to one online page.
So, I ran into a problem: when this page doesn't available, I can't figure it out from my Java code, it looks like form wasn't submitted and clicks on Submit button do nothing, but in Chrome for example I see that the page isn't available.
So, is there an option to check from Java code if page is available?
Thanks in advance and sorry for bad English.
So, I found an answer.
There is Worker class in JavaFX that associates with WebEngine and it has a field with State type.
State is enum that has 6 options:
READY
SCHEDULED
RUNNING
SUCCEEDED
CANCELLED
FAILED
So State.FAILED can be used for handling errors.
For example, something like that (we'll assume we have WebEngine instance):
webEngine.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> {
if (newState == Worker.State.FAILED) {
doOnError();
return;
}
doOnSuccess();
});
webEndgine.load("example.com");
So, every time state is changed ObservableValue#changed will be called with new State value as one of parameteres and if state become FAILED we do some error processing.
Related
This topic is sadly very poisoned by non-applying answers, e.g. 1, 2, 3, 4, etc. pp.
The issue:
One may do an action which, when successful, makes the website raise an alert.
E.g. click on a "logout" button to see an "Are you sure you want to logout?" alert:
public class Logout extends PageObject {
static final Target LOGOUT = /* logout button, which will display the alert when clicked */;
public Performable logout() {
return Task.where("{0} clicks on Logout"
, Ensure.that(LOGOUT).isDisplayed()
, Click.on(LOGOUT) // done manually: alert visible; done by Serenity: no alert
);
}
}
Serenity will cause an org.openqa.selenium.UnhandledAlertException during execution of Click.on and the alert will not be present after this task. If the next task would be "interact with alert" in any way or form (as done in all the linked articles and all others I have perused before posting this question), the next task will then always fail because there is no alert .
This can be easily observed in the browser window as well: The alert may show, if at all, for but a split second and immediately disappear.
The question:
Given that the alert has to be handled before the action causing it completes: How do I do that?
N.b.:
I have done a deeper analysis in this old bug report. Includes a call stack where one may place breakpoints inbetween the alert's appearance and disappearance.
Others have indicated that it is an issue pertaining to chromedriver - but using a different framework with the same chromedriver works just fine.
A workaround might be to disable screenshots, but
I do not want to do that!
Serenity indicates (via a log warning) that this is a user error. So I'd rather correct my error than work around it.
I want to use JavaFX WebEngine in such a way that I can execute Javascript code in order to fill one form and click submit button on the website I opened. I was using ChromeDriver but I didn't like certain aspects of it, WebView fits better for my needs, but as far as I researched, the only way to make sure a page is loaded is to add a state listener to WebEngine and when it's SUCCEEDED, make operations on webpage. However, when I execute Javascript and submit a form, a new webpage opens so it's SUCCEEDED for the second time (first time, opens webpage that contains the form) and it executes the same form-filling code in listener. I want to execute other Javascript code after submitting the form but I couldn't find a good way to do that. In ChromeDriver, I could simply wait for certain amount of time, but with WebView case, because it executes in UI thread, I can't do that. Thanks.
I'm not sure if that's what you mean. SUCCEEDED is just a information about state of engine, to be more accurate you should check other parameters, for instance: If you want to handle different pages inside one listener, you can use location-based (currently loaded url) verification.
WebEngine engine = webView.getEngine();
engine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != State.SUCCEEDED) {
return;
}
String location = engine.getLocation();
if (location.contains("page1")) {
// Do something
return;
}
if (location.contains("page2")) {
// Do something
return;
}
System.out.println("Unhandled location: " + location);
});
I'm new to GWT and I need to get a right click working. The doco I've read suggests that I need to override the onBrowserEvent() method. I'm just experimenting at this stage. the event is processed and my pop-up appears. However, as soon as I close the pop-up, the usual browser drop down menu appears (with options like "Bookmark this page" and such).
I'm using IceWeasel 24.5.0 (FireFox clone for Debian) and, obviously, Debian (wheezy).
Here's the relevant code:
public ActivityTextCell() {
super(BrowserEvents.MOUSEDOWN, BrowserEvents.MOUSEUP);
}
#Override
public void onBrowserEvent(
com.google.gwt.cell.client.Cell.Context context,
Element parent,
ActivityDTO value,
NativeEvent event,
ValueUpdater<ActivityDTO> valueUpdater) {
super.onBrowserEvent(context, parent, value, event, valueUpdater);
event.preventDefault();
event.stopPropagation();
if (event.getType().equals(BrowserEvents.MOUSEUP)) {
Window.alert("mouse up event");
}
else {
switch ( event.getButton()){
case NativeEvent.BUTTON_RIGHT:
Window.alert("right mouseclick");
break;
case NativeEvent.BUTTON_LEFT:
Window.alert("left mouseclick");
break;
case NativeEvent.BUTTON_MIDDLE:
default:
break; // Do nothing
}
}
The class ActivityTextCell extends AbstractCell.
So what am I missing? How do I stop the browser from reaticng to the mouse click?
Well it certainly wasn't a matter of a few minutes (as can be seen by the fact that it has taken me a week to get back to this), but I have a solution. I tried reversing the order of the the event.preventDefault() and super.onBrowserEvent() but it didn't really help.
I tried a little experiment on a normal web page. It turns out, that the MOUSEDOWN event doesn't do anything in that context and the usual browser selection menu appears on the MOUSEUP. So the if/else logic sort of fell by the wayside.
What did the trick is to include the following in the top level GUI class immediately after adding the main page:
RootLayoutPanel.get().addDomHandler(new ContextMenuHandler() {
#Override
public void onContextMenu(ContextMenuEvent event) {
event.preventDefault();
event.stopPropagation();
}
}, ContextMenuEvent.getType());
This has the additional benefit (for my purposes, at least) of preventing the Browser from reacting to a right click anywhere in the application view.
As an aside: The purpose of preventing the default action is to stop the Browser doing its own thing Stopping propagation is possibly not required, but I left it in anyway (propagation goes fro the node up to the root, not the other way around). The purpose of overridinging onBrowserEvent() is to enable your own application to handel that event. The use of super.onBrowserEvent() is to allow the event to be handled by your code in the first place. I've given the relevant reference in my previous comment. The book "GWT in Action" is well worth a read if you're likely to be doing a lot of GWT coding.
You call super.onBrowserEvent() which triggers the standard browser response.
You should move event.preventDefault() to the if part of your code, and super.onBrowserEvent() to the else part. You want one of them executed depending on a browser event, but not both.
I am working on an Eclipse plugin-project where I have multiple services which have to register themselves to the master-project (stored in a list). I have one view where I want to list each service (that successfully registered itself) and its status (if enabled/disabled -> from settings) which should be updated if the status changes.
What i tried:
The adding works as expected and the list in the master-project knows the single services. Now I have problems to show the details (service + it's status). I tried to add a new label for each service (with a for-each-loop). Basically this works, but I don't know how to refresh the view after I get the event (in the view) that a service was added. Moreover I don't know how to bind the propertychanged-event to such a label. (I know how to do it if the labels are hard coded, but that's not possible here).
How can I achieve what I want? (show label & status for each registered service and refresh status if it changes)
Thank you!!
For the sake of completeness, I add my answer/solution I found here:
Eclipse plug-in: bind data to a list and refresh view
I have an web application, which generates a JS message
'Are you sure you want to navigate away from this page?' when you try to open a new page.
I know I can handle this message by
Selenium.getAlert();
(or some modification of it, I haven't tried it yet)
But my main problem is that this message generates only when I leave this page.
In selenium I can leave page by using
Selenium.open("new address");
or
Selenium.back();
So I use code like this
Selenium.open("new address");
Selenium.getAlert();
But the problem is that Selenium.open doesn't finish and go to next code line in program until the new page is fully loaded, but the page can't be loaded until program goes to next code line and handles this alert. So it's ablocked situation and I don't know how to handle it.
I don't think it can be done, staying entirely within the Selenium RC API. I have cases similar to this that I handle by launching an AutoIt script, before the open(), that waits for the prompt and answers it. That only works on Windows, but if you need something for other systems, I'm sure there are equivalent tools.
Selenium has always had a problem with alerts and confirmations (which this is - a confirmation has an OK/Cancel choice) that occur duing page loading. There's even an ancient bug number enshrined in one of the error messages that explains that it can't catch them.
Use:
openAndWait(..)
Maybe this other SO question will help you.
I don't know if this will work, but it's an idea. You could try something like:
try {
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
Selenium.open("new address");
} catch (Exception e) {
// Should throw after 1 second
}
// Now we may be able to interact with the alert.
Selenium.getAlert();