TestFX clicking menu items - java

I'm writing a JavaFX application with a menubar. I have given the menu items CSS ids, and I want to use TestFX to click on them. Here's the code:
clickOn("#menu-file").clickOn("#menu-file-new-project");
When I run this I can see my mouse move to the completely wrong place on the screen, and then the test fails saying it couldn't find any elements matching #menu-file-new-project. I'm assuming it can't find them because it's never opening the File menu, because it's clicking in the wrong location.
What should I do about that?
Windows 10, Java 8u120, TestFX 4.0.6.
For the record it fails the same way in monocle headless mode

Okay, this has nothing to do with the scale and I'm not even sure why it works, but overriding the point method as follows in my Test Application instance seems to work for some reason:
#Override
public PointQuery point(Node node) {
Point2D topLeftPoint = node.localToScreen(0, 0);
Point2D pos = new Point2D(topLeftPoint.getX(), topLeftPoint.getY());
return super.point(node).atOffset(pos);
}

Related

Mobile emulator Selenium tests fail in Jenkins but not in cmd

I have a test that always fail when running inside Jenkins.
My project includes Selenium webdriver, JAVA, Maven, TestNG, Jenkins, Allure (reports).
I have a few suites of tests with 100+ test cases, and I iterate them through 3 different browsers (the tests run in parallel using TestNG). They all run (using maven command line) and pass in my development laptop, and on the test server when using a command line.
I have 2 problems regarding Jenkins and separated them into 2 questions- one of them is described in this question, and the other (IE11 issue) is here.
The problem starts when running inside Jenkins in the test server!
The test fail in mobile emulator (Chrome browser) - in the test I click on a link to verify that a new window was opened with the correct url.
I tried 3 types of clicks (Selenium click, Actions, JS) and all returned a null handle.
The code:
Here I create the main window handle and click the link:
String mwh = driver.getWindowHandle();
WebElement poweredBy = (new WebDriverWait(driver,10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath(Consts.POWERED_BY_XPATH_1000))));
poweredBy.click();
And this is, part of, the method that gets the handle and verify the new window:
public boolean closePopupWindow(String mwh, String mTitle, String layoutNumber) {
// For IE11- make sure popup blocker is turned off in the options. else it will have only one window handle and fail
boolean isOpenedWindowCorrect = false;
String newWindow = null;
Set<String> handlers = driver.getWindowHandles();
for (String window : handlers) {
if (!window.equals(mwh)) {
newWindow = window;
}
}
// the focus is on the main page. need to switchTo new page and close it
driver.switchTo().window(newWindow);
System.out.println("The focus now is on the NEW window");
String newTitle = driver.getTitle();
System.out.println(newTitle);
This is the error I'm getting:
java.lang.NullPointerException: null value in entry: handle=null
at com.google.common.collect.CollectPreconditions.checkEntryNotNull(CollectPreconditions.java:34)
at com.google.common.collect.SingletonImmutableBiMap.(SingletonImmutableBiMap.java:42)
at com.google.common.collect.ImmutableBiMap.of(ImmutableBiMap.java:73)
at com.google.common.collect.ImmutableMap.of(ImmutableMap.java:123)
at org.openqa.selenium.remote.RemoteWebDriver$RemoteTargetLocator.window(RemoteWebDriver.java:995)
at il.carambola.pages.Page.closePopupWindow(Page.java:786)
Do you think there is a security issue that Jenkins wont open new windows in the browser? Is it VERY slow to open the window?
The same tests PASS when not using mobile emulator. (I have the same test in Chrome and Firefox and it succeed to click and pass the verification).
JDK 1.8.0_162
Jenkins V 2.121.1
Server- AWS t2.large - 8GB RAM, Windows server 2016 Data center, 64bit
It's clear that when your program gets to this line
driver.switchTo().window(newWindow);
that newWindow is still null. The way this is written, it could be a timing issue, and it could be another issue causing the popup to not show up. To make sure it's not a timing issue, I would suggest adding some kind of wait for there to be multiple window handles before you try to switch windows. Something like
(new WebDriverWait(driver,10)).until(d -> d.getWindowHandles().size() == 2);
If that wait fails, then you know the popup is being blocked and can go from there.

First addCommand() item in a Form fails when used with native theme

I have encountered a problem when using the the addCommand() method of the Form class along with the Native theme - other themes work fine. See the following example:
Form hi = new Form("Hi World");
hi.addComponent(new Label("Hi World"));
// with native theme - can't click on the first command in the list
hi.addCommand(new Command("Dummy1") {
public void actionPerformed(ActionEvent ev) {
Dialog.show("Dummy1 Clicked!", "You clicked the Dummy1", "OK", null);
}
});
hi.addCommand(new Command("Dummy2") {
public void actionPerformed(ActionEvent ev) {
Dialog.show("Dummy2 Clicked!", "You clicked the Dummy2", "OK", null);
}
});
hi.show();
When I create an application using the code above, a click on the second command ("Dummy2") produces the expected Dialog, but a click on the first command ("Dummy1") does nothing.
This only happens when using the Native theme. If I switch to Flat Blue, then clicking on either command produces the expected Dialog.
This behavior happens both on the Simulator and on a real Android device (don't know about iOS).
Fyi, my toolchain is NetBeans IDE v8.2, Java 1.8.0_25, with the CodenameOne plugin v3.6.0.
Has anyone else seen this? Am I missing something? If so, is there a workaround?
If the element is very narrow and very close to the top the click might be misinterpreted as a click out of bounds or on the status bar area. You need to set the styling of the SideCommand to have a sensible default as this element is very application specific. Otherwise touches might be lost.
I tried styling the SideCommand but it didn't seem to help. What worked for me was to define a style for TitleArea and simply uncheck Derived for the Padding settings (I left them all set to 0px).
I have no idea why this works - I would have thought that the derived values would have been zero in any case.

Robotium - Trying to click home button in app

I'm new to robotium and i'm trying to write a quick and dirty script to run through all screens in an app.
The problem i have mainly with the 'home button' in the app. I've tried lots of options but i cant seem to get it to click there except with index, which is not what i want.
When i check out the button with the hierarchyviewer it looks like this:
Link
However when i try for example:
assertTrue(
"Wait for text (id: myapp.R.id.home) failed.",
solo.waitForImageById("myapp.R.id.home", 20000));
solo.clickOnImage((ImageView) solo.findViewById("myapp.R.id.home"));
solo.waitForActivity("MenuActivity");
It fails at the waitForImageByID line. Ive tried multiple options like waitForImageButton etc, but i just cant seem to get it clicked. What am i missing here?
junit.framework.AssertionFailedError: View with id: '0' is not found!
at com.jayway.android.robotium.solo.Solo.getView(Solo.java:1990)
at com.jayway.android.robotium.solo.Solo.getView(Solo.java:1970)
at com.bitbar.recorder.extensions.OtherUtils.a(OtherUtils.java:246)
at com.bitbar.recorder.extensions.OtherUtils.b(OtherUtils.java:241)
at com.bitbar.recorder.extensions.v.a(Waiter.java:71)
at com.bitbar.recorder.extensions.ExtSolo.waitForImageButtonById(ExtSolo.java:4176)
at com.example.android.apis.test.Test.testRecorded(Test.java:137)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1740)
Use the following line to press the home button in the action bar
solo.clickOnActionBarHomeButton();
The issue is that the id that it is referring is not in your application, it is in androids default R file, try android.R.id.home and it should work fine. It is worth noting though that if your application uses action bar sherlock to support the action bar pre 4.0 that this will have a different ID there and you will have to handle this in your test.
You can see this for yourself looking at: http://developer.android.com/reference/android/R.id.html
When you are using ActionBarSherlock there are two different Ids you have to check, android.R.id.home for API-Level>11 and abs__home for lower levels (provided by ActionBarSherlock):
View homeButton = activity.findViewById(android.R.id.home);
if (homeButton == null) {
homeButton = activity.findViewById(R.id.abs__home);
}
What about this code:
ArrayList<LinearLayout> ll = solo.getCurrentViews(LinearLayout.class);
//You can change 1 with the ordinal number of LinearLayout you want to click.
solo.clickOnView(ll.get(1));
or also
ArrayList<ImageView> iv = solo.getCurrentViews(ImageView.class);
//You can change 0 with the ordinal number of Image you want to click.
solo.clickOnView(iv.get(0));
I think if you identify the correct id for view or linear layout or image view it should work.
Dave C's answer was working only partially for me. The button was clicked but before the preceding screen was loaded assertions had started and thus were always false. The solution is to run "home click" on the main thread (Robotium 5.2.1):
getInstrumentation().runOnMainSync(new Runnable() {
#Override
public void run() {
solo.clickOnActionBarHomeButton();
}
});
From your question I can see that it is an image view. You can click on any view using the following piece of code.
View view = solo.getView("View_name_from_hierachy_viewer");
solo.clickOnView(view);
View_name_from_hierachy_viewer in your case will be "home".
Let me know if this does not work.

JOGL javaw.exe remains running after application is closed

I have a simple java application that uses JOGL. When I run it from eclipse, and then close the application window, javaw.exe remains running. Here is the the relevant code:
public class App {
private Display mDisplay;
private Shell mShell;
private GL4 mGl;
private int mProgramId;
private int mVsId;
private int mFsId;
// ...
public void start() {
if (!initialize()) {
return;
}
while (!mShell.isDisposed()) {
if (!mDisplay.readAndDispatch()) {
mDisplay.sleep();
}
}
destroy();
}
private void initialize() {
mDisplay = new Display();
mShell = new Shell(mDisplay);
// some SWT and opengl initialization code, which is irrelevant for this issue
// (at least I think so)
// getting GLProfile, GLContext, GL4 etc.
final String vsText = ResourceManager.getShaderText(vsPath);
final String fsText = ResourceManager.getShaderText(fsPath);
mVsId = mGl.glCreateShader(GL4.GL_VERTEX_SHADER);
mFsId = mGl.glCreateShader(GL4.GL_FRAGMENT_SHADER);
mGl.glShaderSource(mVsId, 1, new String[] { vsText }, null, 0);
mGl.glCompileShader(mVsId);
mGl.glShaderSource(mFsId, 1, new String[] { fsText }, null, 0);
mGl.glCompileShader(mFsId);
mProgramId = mGl.glCreateProgram();
mGl.glAttachShader(mProgramId, mFsId);
mGl.glAttachShader(mProgramId, mVsId);
// bind a constant attribute location for positions of vertices
mGl.glBindAttribLocation(mProgramId, 0, "in_Position");
// bind another constant attribute location, this time for color
mGl.glBindAttribLocation(mProgramId, 1, "in_Color");
mGl.glLinkProgram(mProgramId);
// here error code is 0x0 (no error)
int error = mGl.glGetError();
mShell.open();
return true;
}
private void destroy() {
// here error code is 0x502 (GL_INVALID_OPERATION)
int error = mGl.glGetError();
mGl.glDetachShader(mProgramId, mFsId);
mGl.glDetachShader(mProgramId, mVsId);
mGl.glDeleteShader(mFsId);
mGl.glDeleteShader(mVsId);
mGl.glDeleteProgram(mProgramId);
mDisplay.dispose();
}
}
I commented out all rendering code and most other opengl/JOGL related calls (besides getting GLProfile, GLContext, GL4 and everything listed in this sample) and this problem persists.
Generally, the application works fine, shaders compile and link without problem (I used validation which I didn't display in this sample) and it displays what it needs to. The only problem is that javaw.exe remains running after I close the application window (by pressing the x in the corner of the window).
This issue is removed only if I comment out mGl.glCompileShader(mVsId); and subsequent lines. If I leave this line, javaw.exe will remain running, so I guess the problem is related to shader initialization/destruction code.
Also, glGetError() returns 0 (no error) at the end of initialize() and 0x502 (GL_INVALID_OPERATION) at the beginning of destroy(). There is only the main loop in between and no opengl calls that I know of, since, for testing, I commented out all rendering code.
Any ideas?
Edit 2012-10-03:
I still don't know what the problem is, but since I updated my graphic card drivers, 'javaw.exe' terminates as it should after application is closed. I have AMD Radeon HD 6870. My current driver version is 8.982 from 2012-07-27, and I can't remember what the last version was, but I believe it was from january 2011 or so.
However, glGetError() still returns 0x502 at the beginning of destroy, so I guess there is still something wrong.
Assuming you use JOGL from jogamp.org, pls use either our SWT GLCanvas
or our NEWTCanvasSWT.
The latter is preferred due to custom GLCapabilities, pls check API doc.
This given plus you are doing everything SWT related on the SWT thread (read
linked unit tests), IMHO it should work - at least our unit tests.
Since you mentioned after an update (GPU/driver) your troubles ceased to exist,
it might have been a driver problem.
Now to your GL error. Trace GL errors can be simply done by setting the system property 'jogl.debug.DebugGL', i.e. on the commandline "-Djogl.debug.DebugGL".
This will install the debug pipeline for your GL object automatically and checks for GL error, which will throw an GLException if appear.
You can also trace via the property 'jogl.debug.TraceGL'.
I don't know if this is relevant or not, but may help someone I guess so I'm gonna share it here. Keep in mind I'm just a hobbyist getting started in Java SWT.
I made a simple application in Eclipse IDE using the Java SWT library. I made a ''Quit'' button in my main Window shell that when pushed calls this :
quitBtn.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
shell.getDisplay().dispose();
System.exit(0);
}
});
After exporting the .jar file to Desktop, I converted it to a .exe file with LaunchJ4 wrapper and check the "Allow only a single instance of the application" in the Single instance tab using the singleR3XPlayer mutex.
When I would close the .exe file with the "Quit" button, everything was fine and the javaw.exe would terminates. But when I closed the shell with the X button on the top-right window, javaw.exe would remains running. I figured that out when I tried to delete the .exe file (Windows "Used file, still open in Java(TM) Platform SE binary, close the file and retry" type of error pop-up) and as I couldn't open another instance of the file after closing it with the X button (because of the Single instance mutex). Also, multiple instances of javaw.exe would remains running if I would execute a few of the .jar file (even after closing them, but only with the X and not the "Quit" button).
I figured out closing the window with the X button would only dispose of the shell and not exit the program. But pressing the "Quit" button would because it called System.exit(0). So I did this :
// SWT Event Loop
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
// To make sure javaw.exe terminates when Window is closed
if (shell.isDisposed()) {
System.exit(0);
}
Hence, after my SWT Event loop is done (shell.isDisposed() == true), I made sure System.exit(0) would be called. This way, javaw.exe is terminated either way.
I don't know how SWT works and I don't know if that's the proper way to do it but it ensures javaw.exe is terminated once the application closes.
Hope that helps.

eclipse RCP - making the IFolder persist after the last View has been closed

I have created an IFolder with a placeholder for my views in RCP on eclipse Helios on XP with Java 1.6 like so;
IFolderLayout mainFolder = layout.createFolder("mainfolder,
IPageLayout.LEFT, (float) 100.0, layout.getEditorArea());
mainFolder.addPlaceholder("myview:*");
And this works as expected with a greyed out area, which is populated by the myview when it is created and with subsequent views. However if the last view is ever closed, the whole IFolder area disappears and future views are instantiated in the wrong area/folder of the workbench.
I see a few people mentioning this problem back in 06, but I can't find any solutions and I don't want to keep force resetting the perspective just when the last folder has gone.
http://dev.eclipse.org/newslists/news.eclipse.platform.rcp/msg15873.html
http://www.eclipsezone.com/eclipse/forums/t53312.html#91951958
I am thinking that I might have to hook the close view method to check to see if it is the last view and re-create the IFolder.
there seems to be a method to prevent the layout from closing;
layout.getViewLayout("myview").setCloseable (false);
layout.getViewLayout("myview:*").setCloseable (false);
but I can't seem to get that to effect the folder from collapsing...
Try this:
Overwrite the method isDurableFolder(...) in your WorkbenchWindowAdvisor so that it looks like this:
#Override
public boolean isDurableFolder(String perspectiveId, String folderId) {
if( "my.perspective".equals(perspectiveId) && "my.mainfolder".equals(folderId) ) {
return true;
}
return super.isDurableFolder(perspectiveId, folderId);
}
Replace my.perspective and my.mainfolder with the ID of your Perspective and Folder. This will create a durable ViewStack for your Folder.
FYI: By default the WorkbenchWindowAdvisor#isDurableFolder(...) returns false. This causes PageLayout#createFolder(...) to create the ViewStack as not durable. The Method PageLayout#createPlaceholderFolder(...) is not able to set the ViewStack durable!

Categories