Selenium WebDriver ElementNotVisible Error for input type='file' element - ruby

I am using selenium webdriver to try and emulate file uploads
I have a file input field:
<input class="upload_file_field" id="main_image_file" label="false" name="banner_image_file" type="file" />
Using this in my test results in a ElementNotVisibleError
#driver.find_element(:id, "main_image_file").send_keys "/Users/dan/Desktop/sample.jpg"
I even tried to change the visibility before trying to upload the file:
#driver.execute_script("arguments[0].style.visibility='visible'; arguments[0].style.display='block'; arguments[0].style.height='100px'; arguments[0].style.width='100px'; arguments[0].style.opacity=1; arguments[0].style.zindex=20", #driver.find_element(:id, "main_image_file"))
It still results in an ElementNotVisibleError
Any advice would be much appreciated
UPDATE
Okay, turns out that there are several conditions which can make an element hidden:
Cannot have 0 opacity
Must have length and width > 0
Cannot be hidden visibility
Display can't be none
transform property can move elements off the page which make it not visible
My problem was with the transform property. it was a way of hiding the input field by transforming it off the page completely so I could use a nicer style button using jQuery file-upload.
After that,
#driver.find_element(:id, "main_image_file").send_keys "/Users/dan/Desktop/sample.jpg"
worked perfectly well in emulating user selection of a file

It simply may be the case that the page didn't load because of some error. Could you try to error out with:
raise(#driver.page_source.to_s)
just before the find_element command?
This way you could make sure that the input field is actually on the page, as seen by Selenium.

you use Ruby but anyway if this question is still actual for you then please take a look at the similar question where I offered the answer How to click on <input type=file> across browsers using Selenium Webdriver?

Related

Capybara - Click element by class name

For what seems to be a simple question I've been on this for a stupidly long time and can't seem to find anything on Google. I have this button I need to click which has no id but a class is included
<button class="filter-case-studies" onclick="initBootpag(filterForContentType('CASE STUDIES', searchHits))" type="button">
<b>CASE STUDIES</b>
(2)
</button>
I've tried using click_on which I now know is only for links and buttons so of course won't work. This is what I have so far:
When(/^I filter the results to only see case studies$/) do
click_on('filter-case-studies')
end
I've also tried page.find('filter-case-studies').click, this too doesn't work.
page.find(:class, 'filter-case-studies').click defualts to :css so this also failed for me.
Is there no way to click an element by the class name in Capybara?
Thanks in advance for the help.
The standard way of doing this in Capybara is
find('button.filter-case-studies').click
In relatively recent versions of Capybara you should also be able to do
click_on(class: 'filter-case-studies')
find('.filter-case-studies').click as recommended here https://robots.thoughtbot.com/write-reliable-asynchronous-integration-tests-with-capybara#find-the-first-matching-element
I had a button that could not be found (Unable to find visible link or button nil with classes [close-modal]) using the methods above.
This worked for me: page.execute_script('$.find(".close-modal")[0].click()')
click_on('.filter-case-studies')
You need the . selector for classes, and # for ids.
Thanks to Mr Schutte for the idea to use . selectors.
I had to use page.find(:class, '.filter-case-studies').click in the end. The absolute navbar got in the way of the button so I then had to include page.execute_script "window.scrollBy(0,500)" to complete the test.

Need help on clicking an element (Element is not clickable at point (62, 459)) - Capybara Ruby Selenium Automation

I am having below error message in my console while trying to click on a button element:
unknown error: Element is not clickable at point (62, 459).
Other element would receive the click: <i class="foo foo-chase-lemon font-size-13"></i>
Here's my code below:
#object = Page.new
#object.wait_until_btn_element_visible
#object.btn_element.click
I have tried with retry 5 times to click on it using rescue but didn't help.
Below code also didn't work where i tried to move to that element before click.
Capybara.page.driver.move_to.(#object.btn_element).perform
Any solution will be greatly appreciated.
I tried increasing the resolution/ scrolling the window. None of them worked on this specific scenario. These solution might work for others.
However, I resolved the issue by clicking the button using javascript "execute_script" method in my automation script.

How to set a span value with capybara?

Does anyone know how to set a value to span tag using capybara?
I tried using element.set or element.send_keys, they only selected the targeted element without modifing the previous value.
<div data-offset-key="bbpvo-0-0" class="_1mf _1mj"><span data-offset-key="bbpvo-0-0"><span data-text="true">aa</span></span></div>
HTML snippet is above, I want to set aa to bb.
Capybara is designed to emulate a user - A user can't edit a span unless there's some sort of javascript widget attached to it. If you have a JS widget attached to the span you would need to perform whatever actions a user would do in order to edit the span. So you say the user has to click on the span and then type on the span - if that is so then you could try something like
span = find('span[data-text="true"]')
span.click
span.send_keys("new content", :enter) # if enter is needed to end the editing
which may work - although I'm going to guess the element actually gets replaced with an input or something after it's clicked on, in which case you need to figure out what those elements are (using the browsers inspector) and then find and use send_keys or set on that element instead
To set text in span value,jquery can be used with capybara as shown below:
page.execute_script("$("<span css selector>").text("testing")");
or
page.execute_script("$("<span css selector>").html("testing <b>1 2 3</b>")");

Selenium webdriver can't find button

EDIT:
I have cleaned this up a bit.
I have a button that looks like this:
<input id="applyRuleButton" class="Button" name="filtersContainer:applyRuleButton"
value="Apply" onclick="wicketShow('applyRuleButton--ajax-indicator');var
wcall=wicketSubmitFormById('id256', '?wicket:interface=:23:form:filtersContainer:applyRuleButton:
:IActivePageBehaviorListener:0:&wicket:ignoreIfNotActive=true',
'filtersContainer:applyRuleButton' ,function() { ;wicketHide('applyRuleButton--
ajax-indicator');}.bind(this),function() { ;wicketHide('applyRuleButton--
ajax-indicator');}.bind(this), function() {return
Wicket.$$(this)&&Wicket.$$('id256')}.bind(this));;; return false;" type="submit">
Firebug:
<input id="applyRuleButton" class="Button" type="submit"
onclick="wicketShow('applyRuleButton--ajax-indicator');var
wcall=wicketSubmitFormById('id2ee',
'?wicket:interface=:29:form:filtersContainer:applyRuleButton::IActivePageBehaviorListener:0
:&wicket:ignoreIfNotActive=true', 'filtersContainer:applyRuleButton' ,function() {
;wicketHide('applyRuleButton--ajax-indicator');}.bind(this),function() {
;wicketHide('applyRuleButton--ajax-indicator');}.bind(this), function() {return
Wicket.$$(this)&&Wicket.$$('id2ee')}.bind(this));;; return false;" value="Apply"
name="filtersContainer:applyRuleButton">
I'm trying to click it and have tried pretty much everything for 2 days, webdriver does not find the element, IDE does find it:
//This was my first approach, it should work.
It works in IDE, but not Webdriver:
driver.findElement(By.id("applyRuleButton")).click();
//then perhaps this should do the trick, hint: It doesn't:
WebElement element3 = driver.findElement(By.id("applyRuleButton"));
JavascriptExecutor executor3 = (JavascriptExecutor)driver;
executor3.executeScript("arguments[0].click();", element3);
Ok, Id not working, I get it.
Then this should work at least:
driver.findElement(By.xpath("//table/tbody/tr/td/div/div/table/tbody/tr[6]/td/input[#id='applyRuleButton']")).click();
It feels like I am missing something obvious here, some help please?
Additional information:
I have added a 5 second wait, the page is completely loaded.
This button is located in a table:
The Xpath is
/html/body/div[4]/div[2]/form/div[3]/div/div/table/tbody/tr/td/div/div/table/tbody/tr[6]/td/input
Webdriver error, no matter what I throw at it, is: Unable to locate element
I have used both 'click' and 'submit', still no success.
I think in this case there are two possibilities :
Either there is another element having same id/xpath.
OR Element present in another iframe.
Is the button visible. Selenium click (latest firefox 26 and latest webdriver 2.39.0) does not sometimes implicitly scroll; Or it may not scroll it fully. So scroll it into view - Scroll Element into View with Selenium and then it should work.
Note Selenium Best Practise try to use By.Id,By.CSSSelector and if nothing gets use By.Xpath in the order of priority. ( Use the FireFinder, FireBug plugin to test XPath or CSS)
This might be a synchronization issue. Such issues can be solved using smart waits.
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementExists((By.Id("applyRuleButton"))));
WebElement element3 = driver.findElement(By.id("applyRuleButton"));
And that should work perfectly fine.
There is absolutely nothing wrong with your selector. I just don't think you're invoking the click correctly.
Try:
driver.findElement(By.id("applyRuleButton")).click();
If this doesn't work, then you might have to invoke a WebDriverWait since you have this question marked as [ajax]
Could you post the entire html?
As a simple experiment, I took the html snippet that you posted and wrote a short python script that invokes selenium:
from selenium import webdriver
br = webdriver.Firefox()
br.get("put your path to snippet here")
button = br.find_element_by_id("applyRuleButton")
print button.get_attribute("name")
button.click()
br.close()
I can find the button and extract the attribute "name" which prints "filtersContainer:applyRuleButton". This is admittedly a very limited experiment, but it suggests that the issue is related to not being where you think you are on the page.
Try this:
driver.findElement(By.Name("filtersContainer:applyRuleButton"));
If this doesn't help, check whether this button is located in any other frame. If so, you may have to find and move your focus to that frame and then locate this button.
First try to identify the button by writting correct xpath using firebug, if you are able to identify button by that xpath then use that xpath while writing your script.
driver.findElement(By.xpath("//input[# type='submit' and # id='applyRuleButton'")).click();
This is ajax application use proper explicit/ webdriver wait till the button gets downloaded
I see that this thread is old, but I was looking at it today (Sept/2021) as I was having the same problem: I could see the name / id/ type of the button, but it would never be found.
I discovered that when I had clicked in a prior link, it opened a new tab in my browser, but Selenium did not change the focus to the new tab, so it couldn't find the ID of the button I was looking for.
I solved it with :
driver.find_element_by_id("export").click() #driver
time.sleep(2)
driver.switch_to.window(driver.window_handles[1]) # Change focus to the new tab
driver.find_element_by_id("0001btn").click() #click
driver.close() #close new tab
switching to a specific frame helped me to resolve the same issue. (python + selenium)
I installed the Selenium Recorder extension on chrome and recorded my steps, and found out that the recorder had a step to select a frame = 0, so adding
self.home_page.driver.switch_to.frame(0)
self.home_page.click_on_element_by_id("clickSubmit")
solved the problem.

How do I identify a dynamic-id custom-type text field in WATiR?

I have this input of type "Submit" that Watir cannot see. I can identify it by ID, but it doesn't turn up in browser.text_fields, or by any other idenfication method. The ID is dynamically generated so I cannot use it for testing. Any ideas on how to make this readable? I'm willing to change the WATiR source code if necessary.
<INPUT id=t8CPm value=Submit type=submit>
I have obviously tried text_field(:value, 'Submit') and text_field(:type, 'Submit'), and I get an "Unable to locate element" error.
Did you try treating it as a button element? Inputs of type submit are generally considered to be a button because the browser generally renders them that way.
try
browser.button(:value, 'Submit').flash
and see if it works for you
I changed INPUT_TYPES to ["text", "password", "textarea", "submit"] in the TextField class of input_elements.rb and there it was.
I should also probably edit the collections to read the type too.
Edit: I am an idiot and I didn't need to do this, but I'm leaving it here in case anyone else needs to identify a real dynamic-id custom-type text field, not a fake dynamic-id custom-type text field otherwise known in my particular case as a "button".

Resources