We are using the GWT provided SimplePager to provide record/page navigation through data sets. We want to test that we are controlling the enabled state of the Next/Previous buttons properly. While SimplePager lets us specify enabled/disabled images for the buttons, the "button" itself is an internal class of ImageButton which extends Image rather than Button. Therefore the resulting HTML does not use Button enabled/disabled attributes, but rather provides a different embedded image for each state.
Is there any reasonable way to detect the SimplePager navigation button enabled states in Selenium?
In standard practice you should create custom component, let say Image button. I would suggest you to use ISFW which provides feature of creating custom component that can be used with annotation. In component you can specify behavior in as per AUT.
Re-writing the code sample to have better formatting.
public class ImageButton extends Component{
public ImageButtom (String loc){
super(locator);
}
#Override
public boolean isEnabled() {
//custom representation!...
return this.getAttribute("class").contains("imgdisabled");
//return this.getCssValue("background").contains("imgdisabled");
//return this.getAttribute("src").contains("imgdisabled");
}
}
You can use this component like Webelement in your test page
#FindBy(locator="locator")
ImageButton prevButton;
#FindBy(locator="locator")
ImageButton nextButton;
In your test code
page.prevButton.verifyEnabled();
page.prevButton.assertEnabled();
Looking at the source code of SimplePager, it looks like they use a generator to create the css styles, where the disabled state (and the enabled state) has a css class applied to it (i m going off this https://code.google.com/p/google-web-toolkit/source/browse/trunk/user/src/com/google/gwt/user/cellview/client/SimplePager.java?r=9614).
So if you can somehow get access to the actual Resources client bundle, then you can call resources.simplePagerStyle().disabledButton() to get a string that is the css class for the disabled button, and you can then use that as a locator in selenium. That might be really tricky tho, because the jvm running your selenium test may not be able to reference the compiled GWT code (i.e., the code that runs when you debug a GWT app).
Alternatively, you can subclass SimplePager, instead of using the DEFAULT_RESOURCES client bundle, pass in your own, and then you get to control the classname used for the disabled button (by making your own Style class, which just wraps the existing one you get from the original client bundle, but add a prefix or something to the return value).
It's a bit messy, because the component is quite encapsulated, and you are trying to get at its innards.
Related
I have a main Layout that contains another UI with grid and a button. This grid shows the data of a table of my database. With the button a wizard gets open, where i can create a new entry to this database. When i close the wizard with a button click, i want the grid to refresh in order to show also the newly added entry. Everythin works fine, including the storage to my database, except the refresh of my grid.
So i have the UI
public class MainLayout{
...
public void refreshGrid()
{
this.grid.getDataProvider().refreshAll();
}
}
where my grid is defined. I already implemented the refresh method.In there is also the button to create a new entry. When i click this button the next UI gets called.
This UI contains the general layout of the wizard, with a tab bar.
public class WizardLayout{
}
In one of those tabs there is finally the UI with the input fields to create the entry. There is also the button to save it to the database.
public class CreateEntry{
...
private void button_onClick(ClickEvent<Button> event)
{
...
}
}
In this button click method the logic is implemented to save it. And after that i would like to call the refresh method from the first UI in order to refresh it. How do i do that, so that it works?
Please remember, everything else works. So my only problem is to refresh the grid because it does not automatically. I have to click the refresh button in my browser to make it work.
First note that while not incorrect, your use of the term UI might be confusing in a Vaadin context, as it's usually used to refer to Vaadin UI objects, of which there is generally one per tab. Communication between Vaadin UIs is more complex than your use case.
There are plenty of solutions for this, the easiest is probably to pass an instance of your MainLayout to your wizard.
In that case, the classes will be tightly coupled, i.e. both depend on each other.
A better way is with some kind of listener or callback. This can be made quite complex, but in the easiest case you just pass a callback that will be run on save.
WizardLayout.java
private final Runnable saveCallback;
public WizardLayout(Runnable saveCallback) {
this.saveCallback = saveCallback;
}
private void button_onClick(ClickEvent<Button> event) {
...
saveCallback.run();
}
MainLayout.java
new WizardLayout(this::refreshGrid);
Is your dataprovider using in-memory items, or do you use a callback dataprovider with lazy loading?
You are probably using an in-memory dataprovider. This is the case, when you load your items from the database and put them in the grid with
grid.setItems(fooService.findAll());
Calling grid.getDataProvider().refresh() will only refresh the items that are already set. Since you have a new item to display, you have to fetch all items again from the DB with your service.
grid.setItems(fooService.findAll());
grid.getDataProvider().refreshAll();
If you're using a callback dataprovider with lazy loading, then I think just refreshing the dataprovider should be enough. I don't know enough about lazy loaded dataproviders to provide a solution to this issue but I do believe this issue should not arise in the first place if using a callback dataprovider
I am working on an eclipse Plugin, and I would like to use an Editor, set some listeners on the current page(good terminology?), and remove these listeners when the user switches on another page (basically, the user is editing several files, as you could do with the default JAVA editor).
For the moment I have written a class extending StructuredTextEditor. The behavior of the plugin was the one expected, but when I try to work on several files, many problems occur. The main problem, according to me, is that I am not able to get notified when the user opens another page.
I read (and tested) a few things about MultiPageEditor, but it seems like it doesn't integrate an XML editor as default editor. How should I proceed in order to get a MultiPageEditor, with XML syntax coloring, and get notified when the user changes the current page to adjust my listeners ?
Thanks for reading.
the code is not perfect but at least you will have an example of a MultiPageEditor integrating an XMLEditor: https://github.com/fusesource/fuseide/blob/8.0.0.Beta2/editor/plugins/org.fusesource.ide.camel.editor/src/org/fusesource/ide/camel/editor/CamelEditor.java
The idea is to call addPage(new StructuredTextEditor()) inside createPages() method.
regards,
In your editor you can listen to selection changes in the editor text using:
getSelectionProvider().addSelectionChangedListener(listener);
where listener implements ISelectionChangedListener.
This applies to any editor derived from AbstractTextEditor (which includes StructuredTextEditor.
You need to do this fairly late in the editor creation. In the createPartControl method works:
#Override
public void createPartControl(final Composite parent)
{
super.createPartControl(parent);
getSelectionProvider().addSelectionChangedListener(listener);
}
I am attempting to create a custom Media Controller by duplicating the source and providing my own layout. The final component is a substitute for PolicyManager.makeNewWindow(mContext);
The PolicyManager class is an internal class and I can not seem to find a way to get a new Window. The documentation suggests new Window(mContext) but eclipse complains that it 'Cannot instantiate the type Window'. Any ideas?
Unless you use the NDK to access private implementations, you cannot actually create a Window. I have done exactly what you are trying with an embedded system, but it is not safe to do for a general purpose app (the underlying implementations have changed and will change again).
Regardless of whether you are using a SurfaceView or TextureView for the MediaPlayer, you should be able to a achieve a similar effect with a regular old transparent custom View. The separate Window shouldn't be necessary. It won't be as easy as copying Android's MediaController code, but it shouldn't be too complicated.
Also, if all you want is a different layout and not a drastic change in functionality, have a look at these two links (the second refers to the first, but it adds commentary & an example project).
When writing a graphical interface, using Java, what's the appropriate way of switching between the different windows of the application, when clicking a button for example? I.E. what are the windows supposed to be, JPanels, JFrames...? And how do all the components 'see' the 'domain controller' (the class that links the graphical package to the application logic package)?
Any guide or reference would be appreciated.
You start your application with your Controller. In the constructor of your controller, you are going to initialize the first GUI you want to open, lets say GUI_A:
private GUI_A gui_a = null;
Controller() {
gui_a = new GUI_A(this);
}
As you might notice, I called the constructor of GUI_A with one parameter: this. this is referencing the instance of the current class, so this is type of Controller. The constructor of GUI_A has to look something like this:
private Controller controller = null;
GUI_A(Controller ctrl) {
controller = ctrl;
}
This is a simple way to get the GUI known to the Controller.
The next thing you would do is displaying GUI_A:
gui_a.setVisible(true);
If you now want to handle button-clicks, you would do it like this:
First, you add the action-performed method to your button. And, as it is best practice in MVC, you don't want to do logic in your view/GUI. So you also create a corresponding method in your Controller for the action-performed, and call it from your GUI:
// Controller
GUI_A_button1_actionPerformed(ActionEvent evt) {
// Add your button logic here
}
// GUI_A
button1_actionPerformed(ActionEvent evt) {
controller.GUI_A_button1_actionPerformed(evt);
}
Usually you don't need to pass the ActionEvent-var to the Controller, as you will not need it often. More often you would read a text out of a TextField and pass it on to your Controller:
// Controller
GUI_A_button1_actionPerformed(String text) {
// Add logic for the text here
}
// GUI_A
button1_actionPerformed(ActionEvent evt) {
controller.GUI_A_button1_actionPerformed(textField1.getText());
}
If you now want to access some fields on your GUI_A from the Controller, be sure not to mark the fields as public in your GUI, but to create public methods which handle how to display the values.
The preferable way is using Actions. You can attach action to each control. When user action happens (e.g. click on button) the appropriate Action is called. Actions can delegate calls deeper into the application logic and call graphical components (JFrams, etc).
suggestion: use tabbed-panel should do this, JPanel is just a Java container, while JFrame should be the outside windows, they are different things. there should be several JPanels on top of One JFrame. your app can have multiple JFrames.
When writing a graphical interface, using Java, what's the appropriate way of switching between the different windows of the application, when clicking a button for example?
Add an ActionListener to the button. In the actionPerformed(ActionEvent) method, do what needs to be done.
I.E. what are the windows supposed to be, JPanels, JFrames...?
I would recommend making the main window a JFrame and using either a JDialog or JOptionPane for most of the other elements. Alternately, multiple GUI elements can be added into a single space in a number of ways - CardLayout, JTabbedPane, JSplitPane, JDesktopPane/JInternalFrame, ..
And how do all the components 'see' the 'domain controller' (the class that links the graphical package to the application logic package)?
One way is to pass a reference to the object between the UIs.
I'm writing a wizard for an Eclipse RCP application. After doing some processing on a file and taking some user input, I don't want to let the user go back to make changes. At this point they must either accept or reject the changes they are about to make to the system.
What I can't seem to find is a method call that lets me override the buttons that display or the user's ability to hit the back button. I'd prefer that it not be there or at least be disabled.
Has anyone found a way to do this using the JFace Wizard and WizardPage?
Usability-wise, am I breaking wizard conventions? Should I consider a different approach to the problem?
You can return null from the getPreviousPage() method in your wizard page implementation.
Expanding on jodonell's answer:
Disabling the back button is harder than it should be, due to non-intuitive behavior in the default implementation of WizardPage.getPreviousPage(). You can call setPreviousPage( null ), and getPreviousPage() still returns the previous page. You need to override the implementation of getPreviousPage() in order to disable the back button:
public abstract class MyWizardPage extends WizardPage {
private boolean backButtonEnabled = true;
public void setBackButtonEnabled(boolean enabled) {
backButtonEnabled = enabled;
getContainer().updateButtons();
}
#Override
public IWizardPage getPreviousPage() {
if (!backButtonEnabled) {
return null;
}
return super.getPreviousPage();
}
}
See my blog post for a few more JFace wizard tips and tricks:
http://nsawadsky.blogspot.com/2011/07/jface-wizard-tips-and-tricks.html
From a UI perspective this seems rather bad. Your users are going to get frustrated if they make a mistake and want to go back and correct it and you don't let them. I think it would be much better to change the application to allow going back rather than looking for ways to prevent it.
There is no way to do this using standard JFace wizard APIs. My team accomplished this by writing a custom WizardDialog. We did this on an Eclipse RCP application and not on an eclipse plugin. Disabling the back button is breaking convention, but our business analysts really wanted the functionality.