I'm using WebDriver with Junit 4.11 and I want to assert that a checkbox is not selected by default, and to do that I'm unsure which constructor method to choose.
The following is from the DOM before the checkbox is selected:
<input type="checkbox" id="c234" name="instantAd" value="true" class="t-checkbox-A">
Then, once the checkbox becomes selected a 'checked' is added, like so:
<input type="checkbox" id="c234" name="instantAd" value="true" checked="" class="t-checkbox-A">
I have tried the following:
WebElement checkBox = chrome.findElement(By.cssSelector("input.t-checkbox-A[name=\"instantAd\"]"));
new WebDriverWait(chrome, 5).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input.t-checkbox-A[name=\"instantAd\"]")));
Assert.assertEquals("null",checkBox.getAttribute("checked"));
checkBox.click();
Assert.assertEquals("true",checkBox.getAttribute("checked"));
The first assertion fails. Perhaps this is because the 'checked' attribute isn't visible in the DOM yet, at a guess.
The stacktrace is displaying:
java.lang.AssertionError: expected: java.lang.String but was: null
I've searched many different posts but none offer me the answer Im looking for, and when checking http://junit.sourceforge.net/javadoc/org/junit/Assert.html for info and guidance (as being new to test automation, Im finding it difficult to work out what I need in my constructor.
Any help would be most appreciated.
There is a less preferable way to achieve the goal, than #mark suggested. (For cases when isSelected() does not work).
boolean isFound = false;
try {
isFound = driver.findElement(By.cssSelector("input.t-checkbox-A[name=\"instantAd\"][checked]")).isDisplayed();
} catch (NoSuchElementException e) {
// Do nothing
}
Assert.assertFalse(isFound);
checkBox.click();
try {
isFound = driver.findElement(By.cssSelector("input.t-checkbox-A[name=\"instantAd\"][checked]")).isDisplayed();
} catch (NoSuchElementException e) {
// Do nothing
}
Assert.assertTrue(isFound);
In short, the code tries to verify if the element with the "checked" attribute is displayed. If it is, then isFound is set to true, else isFound remains false
There are disadvantages:
too much code
the test will spend additional 5 seconds before throwing the NoSuchElementException when the element is not found
The "try" clause can be externalized to a separate method.
With the help from #Francis on SQA Stackexchange I managed to solve the issue to assert a checkbox to be deselected by default.
The code that I had written (posted in my question above) contained the below assertion:
Assert.assertEquals("null",checkBox.getAttribute("checked"));
What I needed (again, thanks to Francis for suggesting this method) was the below assertNull:
Assert.assertNull(checkBox.getAttribute("checked"));
Job done.
Many thanks to all that looked into this.
Related
I use a Vaadin7 com.vaadin.ui.CheckBox with Java 1.8 on a Wildfly Application Server.
I have a PopUpDialog with the following checkbox configuration:
checkBox1.addValueChangeListener(event -> // Java 8
LOGGER.info("property Value: "+ event.getProperty().getValue().toString()+
" getValue Value: "+checkBox1.getValue()));
When I click the checkBox1 in the User Interface in the WebBrowser the ValueChangeListener gets called.
The first property Value "event.getProperty().getValue().toString()" returns the correct true/false state of the checkbox.
But the checkBox1.getValue() which I want to use in my PopUpDialog class methods to access the true/false == clicked/not clicked state of the checkobox returns always false even if I call it in the ValueChangeListener
Can someone help me why the "getValue()" method does not return the correct state ?
-----------------EDIT---------------
One solution is to use the ValueChangeListener to set the value of the Checkbox:
checkBox1.addValueChangeListener(event ->
checkBox1.setValue(
(Boolean) event.getProperty().getValue()
));
But normally the value should be set without a listener setting it manually, correct ?
what is a PopUpDialog class? Is it some add-on? (Haven't found myself by briefly googling)
I've tried your scenario with a PopupView and value is always returned correctly. Vaadin version is 7.7.13
CheckBox cb=new CheckBox();
cb.addValueChangeListener(e->{
System.out.println("Event value" + e.getProperty().getValue());
System.out.println("cb value: " + cb.getValue());
});
VerticalLayout popupContent = new VerticalLayout();
Button getValue=new Button("Value", e->{
Notification.show("CB value:" + cb.getValue());
});
popupContent.addComponents(cb,getValue);
PopupView popup = new PopupView("Pop it up", popupContent);
layout.addComponent(popup);
setContent(layout);
Is there anything I've missed in my example?
Edit: And Checkbox, of course, should return a correct value. Otherwise, it's a bug
On clicking a checkbox, the checkbox is highlighted but its not clicked
and i don't get exception .
<input name="include_notice" onclick="javascript:TogglePublishDates();" type="checkbox">
I identify this checkbox with Name and tried using sendkeysReturn and sendKeysEnter.
Note: This test case was running good for quite a long time.No changes were made in Selenium Web driver or Firefox.
You can try to click using java script, as shown below:
JavascriptExecutor e = (JavascriptExecutor)wd;
e.executeScript("arguments[0].click();", driver.findElement(By.name("include_notice")));
If you still observe the inconsistent behavior, you may want to implement the retry mechanism, as shown below:
//1) Finding the check box
WebElement checkBox = driver.findElement(By.name("include_notice"));
//2) Checking whether check box is already checked
if (!checkBox.isSelected()) {
JavascriptExecutor e = (JavascriptExecutor)wd;
e.executeScript("arguments[0].click();", checkBox);
//3) Checking whether first attempt to check the check box worked
if (!checkBox.isSelected()) {
//4) Retrying
checkBox.click();
}
}
Let me know, if you have any further queries.
You can try with these below codes:
driver.findElement(By.name("include_notice")).click(); //find checkbox element and click on it.
Click checkbox using java-script executor.
WebElement checkbox = driver.findElement(By.name("include_notice"));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", checkbox);
If Checkbox is already selected then use this code.
WebElement checkbox = driver.findElement(By.name("include_notice"));
if (!checkBox.isSelected()) //checkbox is not selected then only it will select the checkbox.
{
checkBox.click();
System.out.println(checkbox.isSelected());
}
When my button is clicked, the ng-hide directive will turn a hidden div to be visible on page. I am using Seleno to write UI test for an Angular application.
I have checked the display css value on that element:
var cssValue = SelectById(elementId).GetCssValue("display");
This cssValue always returns a none.
Also checked is the class attribute.
var cls = SelectById(elementId).GetAttribute("class");
I am expecting ng-hide should be removed from the classes of this element.
return !SelectById(elementId).GetAttribute("class").Contains("ng-hide");
But every time the class still contains ng-hide!
In case someone may ask, here is my SelectById. Just to return a Web Element on the Selenium Page Object.
protected IWebElement SelectById(string id)
{
return Find.Element(By.Id(id));
}
As mentioned in the answer section, I probably did not wait out the class update by Angular in a correct way. What I did is just let the Thread Sleep a while.
public static void Pause(int durationInMilisecond = 2000)
{
if (SelenoSettings.EnablePausing)
Thread.Sleep(durationInMilisecond);
}
Anyone can give me some advice? Thanks.
Here is our solution, thanks to the input from ABucin and Arran. Thank you for pointing to the right direction for us. WebDriverWait is the thing we should look into in this case.
public bool Displayed(string elementId)
{
try
{
var wait=new WebDriverWait(BrowserFactory.Chrome(),new TimeSpan(0,2,0));
wait.Until(d => !SelectById(elementId).GetAttribute("class").Contains("ng-hide"));
// then there is all types of checking start to work:
var bySelenoDisplayed =SelectById(elementId).Displayed;
return bySelenoDisplayed;
var byCss = SelectById(elementId).GetCssValue("display");
return !byCss.Equals("hidden");
var byClass = SelectById(elementId).GetAttribute("class");
return !byClass.Contains("ng-hide");
}
catch (Exception)
{
// 2min timeout reached.
return false;
}
}
According to the Angular ngHide documentation (https://docs.angularjs.org/api/ng/directive/ngHide), "The element is shown or hidden by removing or adding the ng-hide CSS class onto the element.". So your best way of approaching this, is to:
click on button
wait for the class to be toggled off
check that class is not present
I believe your problem is that the class removal does not happen immediately, but after a certain period of time. I have had several issues regarding this with Selenium on Java, and I assume this is the problem in your case, as well.
I'm using a custom validator on my combobox's:
function(v) {
console.log(v === 'some value I know for SURE is in the store'); // (1)
var index = this.getStore().findExact(this.displayField, v);
return (index!==-1) ? true : 'Invalid selection';
}
Basically admits the same set as forceSelection but allows the user to type arbitrary text to attempt to auto-complete.
However; I'm having really odd results with findExact(). For example, if the combobox's value is currently valid, and a user does a space + backspace, the validator will fail, even though the output of (1) is true.
Any ideas what is causing the problem? The end-experience is currently very buggy-feeling..
When you type additional space, store is filtered. After you press backspace, and validator is fired, store is still empty.
If you have local store, then you could validate combo with some delay after each change. Example:
listeners: {
change: function() {
this.validate();
},
delay: 100
}
That should be enough.
On the other hand if you have remote store, try something like this:
validator: function(v) {
var store = this.getStore(),
index = store.findExact(this.displayField, v);
if (index === -1 && store.isLoading()) {
store.on('load', function() {
this.validate();
}, this, { single: true, delay: 100 });
}
return (index !== -1) ? true : 'Invalid selection';
}
I had a similar issue and found this entry. My problem was, that I reused the same store instance across multiple ComboBoxes. After giving each ComboBox an own store with cloned data, everything was fine.
See also:
https://www.sencha.com/forum/showthread.php?305182-ComboBox-forceSelection-clears-input&p=1127218&viewfull=1#post1127218
I just spent a few days on this issue and found a really great solution (by accident, really). You can - as the accepted answer suggests - utilize the provided validator function; however, from my understanding, there is a much simpler solution than the accepted answer provides: evaluating whether or not the user-provided input equates to a value in the store (which is the underlying question in the original post).
The advantage of thinking about the input in this way is that it enables us to handle the use case of an invalid value entered by the user (validated; no value) and - after the field loses focus - Ext JS sets the field back to its previous value (which remembers its store value).
This is an entirely different route than your thinking, but it should work, especially as .validate() runs regardless of whether you provide an implementation of the validator procedure:
validator : function(someParam) {
if(this.value === null) {
return "error message"; //falsy
} else {
return true;
}
}
If you enable forceSelection, the above works, very well, and gets rid of the buggy feeling. This allows you to rely on the .validate to do its magic elsewhere (notice I don't even call it; read the doc. to figure out when its called in relationship to validator) and not have to worry about what the user correctly explains in the accepted answer.
We were having trouble with forceSelection clearing user text before they were finished typing. We seemed to get what we needed by setting forceSelection false and just checking that they selected something.
validator: function(v) {
if (this.getSelection() === null) {
return 'invalid text';
}else{
return true;
}
}
I am new to NatTable. I have gone thorough the NatTable examples and its source code but am not getting a solution to one of my problems.
In the NatTable I have a column that should provide a checkbox for selection depending on the value of another column.
I have used Checkboxpainter, checkboxcelleditor, the defaultbooleanconverter and IEditableRule. This renders a checkbox irrespective of whether the cell is editable or not though it allows me to mark the checkbox only if it is enabled.
However as per our requirement user should not see the checkbox if the row is not selectable. or in worst case a disabledcheckbox should be rendered for rows that are not selectable.
Can someone please help me out?
Thanks and regards,
Pradyumna
Got a solution for this.
I had to write a custom checkboxpainter (inheriting from the one that is available OOTB) and override its getImage method to return null for appropriate cells
There is a better solution which I have just applied to a similar case in my work.
I did it by adding the following configuration to the table:
// make checkbox cells editable
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITABLE_RULE, IEditableRule.ALWAYS_EDITABLE, DisplayMode.EDIT, CONFIG_LABEL_CHECKBOX);
// register the checkbox editor for DisplayMode.EDIT
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new CheckBoxCellEditor(), DisplayMode.EDIT, CONFIG_LABEL_CHECKBOX);
// register the checkbox painter for DisplayMode.NORMAL
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, new CheckBoxPainter(), DisplayMode.NORMAL, CONFIG_LABEL_CHECKBOX);
// register the painter for empty cells in DisplayMode.NORMAL
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, new BackgroundPainter(), DisplayMode.NORMAL, CONFIG_LABEL_EMPTY);
Basically, this introduces the configuration labels CONFIG_LABEL_CHECKBOX for an editable checkbox, and CONFIG_LABEL_EMPTY for an empty cell.
Now all you have to do is to attach an IConfigLabelAccumulator to your bodyDataLayer:
bodyDataLayer.setConfigLabelAccumulator(new IConfigLabelAccumulator()
{
public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition)
{
if(columnPosition == CHECKBOX_COLUMN_INDEX)
{
if(someCodeToCheckIfRowIsEditable(rowPosition))
{
configLabels.add(CONFIG_LABEL_CHECKBOX);
}
else
{
configLabels.add(CONFIG_LABEL_EMPTY);
}
}
}
}