I have a iframe, then a widget that contains the create invoice button. It is not inside the iframe but outside of it and I cannot access it.I cannot access this dialog using selenium webdriver java, Im trying to access the create invoice button using java:
</div><div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"><div class="ui-dialog-buttonset"><button type="button" id="saveBtnDialog" class="btn btn--primary">Create Invoice</button><button type="button" id="CancelBtnDialog" class="btn btn--primary">Cancel</button></div></div></div>
my code:
private final By createInvoiceBtn = By.id("saveBtnDialog");
driver.switchTo().frame(driver.findElement(By.cssSelector(".ui-dialog-buttonset")));
driver.findelement(createInvoiceBtn).click();
As my understanding if your button is not inside a frame and you are already in the frame
You need to switch from frame to defaultContent and then go to find element and perform action as below :-
//first switch to out side the frame
driver.switchTo().defaultContent();
//now implement WebDriverWait to provide wait
WebDriverWait wait = new WebDriverWait(driver, 100);
//wait until ExpectedConditions is not true
WebElement buttonEl = wait.until(ExpectedConditions.elementToBeClickable(By.id("saveBtnDialog")));
//now you go for the action
buttonEl.click();
Hope it will help you...:)
Related
I've tried
File file = new File("/Users/swapnil.kotwal/Desktop/AntVsGradle.jpg");
driver.findElement(By.xpath("//input[#class='libray_create-resource_choose-file_hidden-input']")).sendKeys(file.getAbsolutePath());
And My HTML is something like below
<div class="libray_create-resource_choose-file">
<button class="btn is-hollow_blue libray_create-resource_choose-file_button undefined">Choose File</button>
<input type="file" class="libray_create-resource_choose-file_hidden-input">
</div>
<div class="library_create-modal_footer">
<button class="btn is-text_only btn-cancel undefined">Cancel</button>
<button class="btn is-filled_blue undefined" disabled="">Add</button>
</div>
I found that file input which is hidden got the file path set properly.
The problem is there Choose File button element is different from file input element //input[#class='libray_create-resource_choose-file_hidden-input']"
There seems to some JS event which make final Add button enable on click of Choose File button.
So, I imported file into file HTML element but how can I enable Add button?
I tried to make that button enabled
WebElement yourButton= driver.findElement(By.className("is-filled_blue"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].removeAttribute('disabled','disabled')",yourButton);
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(yourButton));
It makes that button visible but still not allow to actually click on it.
First let me say that -- I don't program in Java, -- but I do a lot of selenium coding in Python.
When I was looking at this question from purely a selenium view point I noted that you aren't selecting the choose file button prior to sending your input. I would assume that you have to select this button to enable the element - btn is-filled_blue undefined
Here is some pseudocode that might help trigger that button to switch from disabled to enabled.
File file = new File("/Users/swapnil.kotwal/Desktop/AntVsGradle.jpg");
WebElement select_button = driver.findElement(By.xpath("//*[#class='btn is-hollow_blue libray_create-resource_choose-file_button undefined']"));
select_button.click();
WebElement upload_file = driver.findElement(By.xpath("//input[#class='libray_create-resource_choose-file_hidden-input']"));
upload_file.sendKeys(file.getAbsolutePath());
/* You might need to send an Enter, Return or Tab before the
add_file_button changes. This process requires testing on the website.
upload_file.sendKeys(Keys.ENTER);
upload_file.sendKeys(Keys.RETURN);
upload_file.sendKeys(Keys.TAB);
*/
boolean add_file_button_presence = driver.findElement(By.className("is-filled_blue")).isDisplayed();
boolean add_file_button_enabled = driver.findElement(By.className("is-filled_blue")).isEnabled();
if (add_file_button_presence==true && add_file_button_enabled==true)
{
WebElement add_file_button = driver.findElement(By.className("is-filled_blue"));
add_file_button.click();
}
Since I don't normally program in Java the structure and syntax of my pseudocode could be incorrect. If it is please let me know and I will either delete this answer or correct the issues with some research.
That undefined class looks suspect - try removing it by adding another js call:
js.executeScript("arguments[0].style.removeProperty('undefined')",yourButton);
My suggestion would be always limit the usage of JavaScript(JavascriptExecutor) code to an extent it simulates the end user action and not manipulates the application behavior
like enabling a button which is disabled functionally etc.
Our purpose is to simulate the application steps in the same way how an end user would use it.
I would suggest to use any third part tool like AutoIt/Sikuli to handle this case since sending file path doesn't enable the 'Add' button automatically as expected
1)Click on the 'Choose File' button using Selenium which opens the upload window, which is not a web component.
2)Since Upload window is not a web component Selenium doesn't support it.
3)Use any third party tools like AutoIt/Sikuli to handle the Windows upload popup by setting the filepath and submit.
4)As we are uploading the file in the UI in the same way how an end user would do, 'Add' button will be enabled automatically.
AutoIt
Try to use JavascriptExecutor to click it too, before you remove disabled attribute.
WebElement element = driver.findElement(By.xpath("xpath"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();", element);
If you use JavascriptExecutor you dont need to make it visible
I managed to upload file by using below hack... I never click on Choose File link/button which was launching Upload File Windows pop-up and by any mean that windows pop-up was not going away.
Tried below options.
1.
select_button.click();
select_button.submit();
action.sendKeys(Keys.ESCAPE).perform();
select_button.sendKeys(Keys.ESCAPE);
robot = new Robot();
robot.keyPress(KeyEvent.VK_ESCAPE);
robot.keyRelease(KeyEvent.VK_ESCAPE);
none of this hiding that pop-up on Mac OS
So, I found a Jugad(#hack in English) I never click on Choose File button which were launching that Upload File Window
public void uploadFile() {
WebElement element = driver.findElement(By.className("libray_create-resource_choose-file_hidden-input"));
element.sendKeys("/Users/swapnil.kotwal/projectName/automation.pdf");
WebElement addButton = driver.findElement(By.className("is-filled_blue"));
// click was important, thanks to this answer in this thread https://stackoverflow.com/a/67095019/1665592
driver.executeScript("arguments[0].click();", addButton);
driver.executeScript("arguments[0].removeAttribute('disabled','disabled'); arguments[0].style = \"\"; arguments[0].style.display = \"block\"; " +
"arguments[0].style.visibility = \"visible\";", addButton);
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(addButton));
addButton.click();
}
I am not able to click on the submit button inside the modal. It only works sometimes - it's not stable.
Below is my HTML element:
<button id="submit-btn" name="submit" data-dismiss="modal" type="submit" class="btn btn-info btn-sm submit projectSaveBtn">Submit</button>
Here I'm using id for locating the element, but I'm not able to click on the submit button inside the modal.
My Java code:
WebElement element1 = driver.findElement(By.id("submit-btn"));
Actions actions = new Actions(driver);
actions.moveToElement(element1).build().perform();
wait.until(ExpectedConditions.elementToBeClickable(element1)).click();
When we use the action class, selenium takes mouse and keyboard controls. If we interact with mouse or keyboard at the time of test execution (specially the actions statement execution), it may fail some times.
You can try with actions class and don't interact until it completes the test execution. it may solve your issue.
Instead of using the id attribute you can use an xpath as follows :
WebElement element1 = driver.findElement(By.xpath("//button[#id='submit-btn']"));
element1.click();
or
WebElement element2 = driver.findElement(By.xpath("//button[#class='btn btn-info btn-sm submit projectSaveBtn' and #id='submit-btn']"));
element2.click();
If it's a windows modal dialog box, you might want to first switchTo() to the modal and then perform accept() on it.
driver.switchTo().alert().accept();
driver.switchTo().window("");
I solved the issue, it was timing issue .Modal was opened before the page loaded properly so giving the time before clicking/opening modal solves the issue .
Here is my code -->
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement add = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.btn.projectAddBtn")));
add.click();
This solved my issue.Thank you all for the support :-)
I have submit button, which is only one on the page, and it's in form.
html part:
<form class="search-form ng-touched ng-dirty ng-valid" novalidate="" style="" xpath="1">
<div class="row">...</div>
<div class="row">...</div>
<div class="row">...</div>
<div class="form__actions" xpath="1">
<div class="form__buttons">
<!---->
<div class="btn__wrapper">
<button class="btn btn__primary" type="submit">
Select My Car
</button>
</div>
</div>
</div>
</form>
So, I'm taking xpath:
//button[#type='submit']
I'm successfully pressing it via submit() (let me skip WebDriver init, its fine):
WebElement searchButton = driver.findElement(By.xpath("//button[#type='submit']"));
searchButton.submit();
(and some search performs)
But when I'm trying to press it via click()
WebElement searchButton = driver.findElement(By.xpath("//button[#type='submit']"));
searchButton.click();
it's not pressed in browser which is launched, and same time Junit test is green (not test, but just pressing button):
#Test
public void test() {
WebElement button = driver.findElement(By.xpath("//button[#type='submit']"));
button.click();
}
Can please someone explain, why submit() successfully presses button in such case, but click() - no. And I do not understand, why "test" is green, when we are trying to click(), but it was not performed, if looking on browser launched by driver.
UPDATED:
I tried
WebElement button = driver.findElement(By.xpath("//button[#type='submit']"));
if (button.isEnabled()) {
button.click();
}
and
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(button)).click();
but still the same - submit() works fine, click() - does not.
The method object.submit() is there for submitting the form to the server. It has another advantage, in case if you're not able to locate the "submit" button then you can take any object of the form and trigger submit() function.
It seems in searchButton.submit(); searchButton is an element of the form and the submit action on it triggers submission of form on server.
Now, why searchButton.click(); not working here could have following reasons.
The button is visible but not enabled.
Driver is finding the 2
instances of searchButton element.
Suggestion: Evaluate following code and check it returns more than one element. If it does then you're clicking on the wrong instance.
List<WebElements> e = driver.findElements(By.xpath("//button[#type='submit']"));
Also try,
driver.findElement(By.xpath(".//button[#class='btn btn__primary'][#type='submit']")).click()
http://docs.seleniumhq.org/docs/03_webdriver.jsp#user-input-filling-in-forms
submit()
submit() method is defined as :
void submit()
Throws:
NoSuchElementException - If the given element is not within a form
As per the JavaDocs when you invoke submit() on an WebElement, if this current element is a form, or an element within a form, then this will be submitted to the remote server. If this causes the current page to change, then this method will block until the new page is loaded.
click()
click() method is defined as :
void click()
Throws:
StaleElementReferenceException - If the element no longer exists as initially define
As per the JavaDocs when you invoke click() on an WebElement and if this causes a new page to load, you should discard all references to this element and any further operations performed on this element will throw a StaleElementReferenceException. Note that if click() is done by sending a native event (which is the default on most browsers/platforms) then the method will not wait for the next page to load and the caller should verify that themselves. There are some ExpectedConditions for an element to be clicked. The element must be visible and it must have a height and width greater then 0.
Your Usecase :
In your usecase, the target WebElement //button[#type='submit'] is within a <form> tag. You are able to successfully press it via submit() as it blocks the method untill the new page is loaded completely as a result of submission on the previous page. Hence the following works :
WebElement searchButton = driver.findElement(By.xpath("//button[#type='submit']"));
searchButton.submit();
But when you try click() method as below, click() being a native event doesn't waits for the new page to load completely. Hence invoking click() method fails.
WebElement button = driver.findElement(By.xpath("//button[#type='submit']"));
button.click();
Your Code Trials :
Validating the button.isEnabled() condition won't fetch us the required result if the element is clickable or not as isEnabled() validates Is the element currently enabled or not? This will generally return true for everything leaving out the disabled input elements. But necessarily isEnabled() wouldn't be validating if the WebElement is visible, interactable and clickable or not.
Solution :
As per the details provided, the solution to invoke click() method would be to induce WebDriverWait with ExpectedConditions clause set to elementToBeClickable as below :
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#type='submit']"))).click();
Update :
Best Practice :
As per the updated HTML and your subsequent comment where you mentioned about Angular4 being used in your app, a much more effective way would be to construct the xpath mocking the HTML DOM as follows :
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//form[#class='search-form ng-touched ng-dirty ng-valid']//button[#class='btn btn__primary' and #type='submit']"))).click();
When I am running the below code run, it only works if I actually manage to scroll to the radio button to get it on the screen in time, otherwise the radio button is not selected.
HTML
<label><input name="GenericID1" type="radio" value="5625"> Sample;| Sat/15/805B</label>
WebDriver
WebDriver driver = new FirefoxDriver();
driver.get("http://samplewebste.com");
WebElement oCheckBoxTest = driver.findElement(By.cssSelector("input[value='5625']"));
oCheckBoxTest.click();
Does anyone have any idea why I actually have to manually scroll to the radio to get it to select actually work, otherwise the command just seems to be ignored without throwing any exceptions?
Try following code to scroll to required element and click on it:
WebElement oCheckBoxTest = driver.findElement(By.cssSelector("input[value='5625']"));
Actions actions = new Actions(driver);
actions.moveToElement(oCheckBoxTest);
actions.click();
actions.perform();
If it not works, try with JavaScript:
WebElement oCheckBoxTest = driver.findElement(By.cssSelector("input[value='5625']"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", oCheckBoxTest);
oCheckBoxTest.click()
I have an Image Refresh button in a same frame under two tables with same Img source and class name but onclick is different for the Refresh buttons.
This is the HTML coding for Refresh buttons.
For the first refresh button:
<SPAN class=AddNew onclick=fnRefreshCAStatus();>
<IMG src="../../SWB/BulkUpload/Images/refresh.gif"> Refresh</SPAN>
For the second Refresh button:
<SPAN class=AddNew onclick=fnGetCAAttributeCount()>
<IMG src="../../SWB/BulkUpload/Images/refresh.gif"> Refresh </SPAN>
Please help me to proceed.
Ideally, you would define (differing) id attributes for both spans and then do
WebDriver driver = getWebDriver();
driver.findElement(By.id("firstSpan")).click();
If you leave the HTML as is (which I wouldn't recommend), you would do
int index = 1; // for the second span
WebDriver driver = getWebDriver();
driver.findElements(By.className("AddNew")).get(index).click();
You can do it with Xpath indexing. Like,
Fist find all the refresh buttons on the page with,
List<WebElement> refreshBtn = driver.findElements(By.xpath("//*[text()='Refresh']"));
Then if you want to click first refresh button use,
refreshBtn.get(0).click();
if second,
refreshBtn.get(1).click();