Having problem in file upload using selenium - java

I am learning to automate procress in a website. I chose http://logos.iti.gr/logos/ as a website to automate. I am facing a problem when uploading the image file using the upload an image button because this button when clicked seems to convert into a text field.
The other tutorials I followed get the id of the text field and use sendkeys to send the path because they do have separate text field and upload button key.
Here is the code that I tried :
driver.get("http://logos.iti.gr/logos/");
driver.findElement(By.id("fileToUpload")).clear();
System.out.println("Cleared");
driver.findElement(By.id("fileToUpload")).sendKeys("/home/test.jpg");
I don't know what the problem is. It just get IPDL protocol error: Handler returned error code!
org.openqa.selenium.ElementNotInteractableException: Element <input id="fileToUpload" class="input_file" name="fileToUpload" type="file"> could not be scrolled into view
Build info: version: '3.141.5', revision: 'd54ebd709a', time: '2018-11-06T11:42:16'

You get ElementNotInteractableException - it is thrown to indicate that although an element is present on the DOM, it is not in a state that can be interacted with. In your case it happens because the element has style display:none. Basically, selenium (and real users as well) can't interact with non-visible elements. You need to make element visible at the frist place and then continue.
driver.get("http://logos.iti.gr/logos/");
WebElement el = driver.findElement(By.id("fileToUpload"));
System.out.println("Making element visible");
((JavascriptExecutor)driver).executeScript("arguments[0].style.display = 'block';", el);
el.clear();
System.out.println("Cleared");
el.sendKeys("/home/test.jpg");
By the way here is the default element style (you can see it in browser dev tools). Pay attention to display:none. When you change the value to block don't be confused that you actually don't see any changes on a screen because element's width and height are very small.
.input_file {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
display: none;
}

Try updating your client and Firefox. Hopefully that should solve this issue.
I have never faced any issue with file uploads until the webpage mandates the dialog box while clicking the image upload. I am using latest version of ChromeDriver and Chrome.
If possible, you too switch to ChromeDriver since I find the pair working seamlessly together in my experience! :)

Related

Element not found when executing findElement in Selenium

I'm trying to fill in multiple forms that come after each other, all the forms get filled swiftly with no errors because I make sure to add
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("")));
before doing anything on a new page, and I know I'm on the correct page.
On the last form, I encounter this error :
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element: //*[#id="formtovalidate"]/fieldset[1]/div/label/input For documentation on this error, please visit: https://www.seleniumhq.org/exceptions/no_such_element.html
So I went to check on the browser by taking a screenshot and the browser is on the correct page with the correct form, I also checked the xpath values and even tried other attributes.. nothing seemed to work.
So I went ahead and printed out the PageSource which showed a totally different page (not the previous page), I also noticed the this page flashed for a second before the final form appeared.
I also tried driver.navigate().refresh() but that didn't work. I kept searching and looking but nothing appeared. I also changed browsers, that did nothing..
This is the method I'm trying to execute:
private void method() {
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[#id=\"formtovalidate\"]/fieldset[1]/div/label/input")));
driver.findElement(By.xpath("//*[#id=\"formtovalidate\"]/fieldset[1]/div/label/input")).sendKeys(email); }
Update
Here's the form screenshot:
Here's the execution results:
Code:
String body_text = driver.findElement(By.tagName("body")).getText();
System.out.println(body_text);
Result: The form but in text
Code:
String body_innerHTML = driver.findElement(By.tagName("body")).getAttribute("innerHTML");
System.out.println(body_innerHTML);
Result: A different page :(
<zendesk-ticketing-form base-url="https://www.runescape.com/a=870/c=K0aO9WO69EI" css-cachebust="129" sitekey="6Lcsv3oUAAAAAGFhlKrkRb029OHio098bbeyi_Hv" grecaptcha="" has-valid-session="true" weblogin-url="https://secure.runescape.com/m=weblogin/a=870/c=K0aO9WO69EI/loginform?mod=www&ssl=1&dest=zendesk/support-form?form=360000065898">
<div class="x-display-none ie-error-display" data-js-ie-error="">
<section class="c-article">
<div class="c-article__content">
<h1>Error: Unsupported Browser</h1>
<p>
We do not support your web browser. Please use a supported web browser by choosing one below.
<br>
FireFox
<br>
Chrome
</p>
</div>
</section>
</div>
Code:
String pagesource = driver.getPageSource();
System.out.println(pagesource);
Result: Same as the previous one.. different page..
Firefox Page Source: https://pastebin.com/Kv15V2SK
Firefox Inspect Element of the page screenshot: http://prntscr.com/qvi6hc
This is weird, as the page source is different to the form!
I couldn't find time to solve your problem. If you want to do it on your own, please Search this on Google, "Shadow Root, Selenium", I had this kind of error before. What I know is, you cannot directly reach an element that stays inside of a shadow root, This is why you are not getting the source code inside of it.
What you need to do is go through the element step by step:
You have to expand the shadow root,
Here is shadow root expand function:
public static WebElement expand_shadow_element(WebElement element)
{
WebElement shadow_root = (WebElement)((JavascriptExecutor)driver).executeScript("return arguments[0].shadowRoot", element);
return shadow_root;
}
You can imagine this function like
.switchTo.frame()
for now..
After some researches you will understand the shadow root.
I hope I got the problem right..
Try this function, If you cannot, I will help you later on. Good Luck.
The PageSource from the <body> tag, containing...
<zendesk-ticketing-form base-url="https://www.runescape.com/a=870/c=K0aO9WO69EI" css-cachebust="129" sitekey="6Lcsv3oUAAAAAGFhlKrkRb029OHio098bbeyi_Hv" grecaptcha="" has-valid-session="true" weblogin-url="https://secure.runescape.com/m=weblogin/a=870/c=K0aO9WO69EI/loginform?mod=www&ssl=1&dest=zendesk/support-form?form=360000065898">
<div class="x-display-none ie-error-display" data-js-ie-error="">
<section class="c-article">
<div class="c-article__content">
<h1>Error: Unsupported Browser</h1>
<p>
We do not support your web browser. Please use a supported web browser by choosing one below.
<br>
FireFox
<br>
Chrome
</p>
</div>
</section>
</div>
...implies that the WebDriver driven Browsing Context was detected as a BOT and the navigation was blocked due to presence of reCAPTCHA.
There are different approaches to solve captcha / recaptcha. You can find a couple of relevant discussion in:
How to bypass Google captcha with Selenium
Selenium webdriver: Modifying navigator.webdriver flag to prevent selenium detection
Update
From your comments now it is clear that you want to fill up the fields within the form:
At this point it is worth to mention that you had been redirected to this page for either of the following reasons:
You EmailID / UserID is banned / blocked from accessing the site.
You EmailID / UserID is black-listed from accessing the site.
As you have used a BOT to access/scrape the site which may have violated the T&C.
Solution
It would be tough to propose a solution to automatically fillup the fields as presumably the elements in the BAN APPEAL REQUEST page may be protected by Invisible reCAPTCHA and you may have to Programmatically invoke the challenge
As others have suggested, it appears RuneScape's website has detected that you're using a bot to interact with their site. It doesn't matter that you solved the captcha manually, as they can still detect automated behavior quite easily without one (and no, the navigator.webdriver flag is not their only way to detect this).
The captcha is meant to prevent automated interaction with their site, which means they don't want you using Selenium/WebDriver to interact with it. You should respect this, especially as it seems you want your account unbanned (going by the pasted snippets and screenshots), so trying to do exactly what they don't want won't win you any favors.

org.openqa.selenium.NoSuchElementException: Returned node (null) was not a DOM element when trying to locate card-fields-iframe by CssSelector

I am trying to locate an iframe by partial id. For this method, I used:
driver.switchTo().frame(driver.findElement(By.cssSelector("iframe[id*='card-fields-number']"))); I have also tried xpath.
driver.switchTo().frame(driver.findElement(By.xpath("//iframe[contains(#id,'card-fields-number')]")));
However, I still receive this exception:
org.openqa.selenium.NoSuchElementException: Returned node (null) was not a DOM element
I found out that when I enable javascript for HtmlUnit, it is able to locate the frame, and switch to it. I would rather not enable javascript as it runs very slow for me, and adds unneeded delay.
iFrame HTML code:
<iframe class="card-fields-iframe" frameborder="0" id="card-fields-number-7pbvqg7azsf00000" name="card-fields-number-7pbvqg7azsf00000" scrolling="no" src="https://checkout.shopifycs.com/number?identifier=438599641d0ed8fe61c161d72e62b5f8&location=https%3A%2F%2Fshopnicekicks.com%2F2192362%2Fcheckouts%2F438599641d0ed8fe61c161d72e62b5f8&dir=ltr&fonts[]=Lato" title="Field container for: Card number" style="height: 43px;"></iframe>
iFrame ID is dynamic, so that is why I resort to using partial ID.
Website link: https://shopnicekicks.com/checkout
You must fill everything out until you reach the last page, which is the credit card information page.
Update
The iFrame is inside of the parent frame.
Parent Frame:
<iframe srcdoc="<script>!function(){var e=function(e){var t={exports:{}};return e.call(t.exports,t,t.exports),t.exports},t=function(){function e(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}return function(t,n,i){return n&&e(t.prototype,n),i&&e(t,i),t}}(),n=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},i=function(e){return e&&e.__esModule?e:{"default":e}},o=e(function(e,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var o=function(){function e(){var t=this;n(this,e),this.calls=[],window.ga=function(){for(var e=arguments.length,n=Array(e),i=0;i<e;i++)n[i]=arguments[i];return t.gaCall(n)}}return t(e,[{key:"gaCall",value:function(e){var t=this;this.calls.push(e),clearTimeout(this.timeout),this.timeout=setTimeout(function(){t.calls.length>0&&t.sendMessage()},0)}},{key:"listen",value:function(){var e=this;window.addEventListener("message",function(t){return e.receiveMessage(t)},!1)}},{key:"sendMessage",value:function(){window.parent.postMessage({type:"analytics",calls:this.calls},this.origin),this.calls=[]}},{key:"receiveMessage",value:function(e){if(e.source===window.parent&&"checkout_context"===e.data.type){this.origin=e.origin,window.Shopify=e.data.Shopify,window.__st=e.data.__st;try{window.additionalScripts()}catch(e){console.error("User script error: ",e)}}}}]),e}();i["default"]=o});e(function(){"use strict";var e=i(o);!function(){(new e["default"]).listen()}()})}("undefined"!=typeof global?global:"undefined"!=typeof window&&window); window.additionalScripts = function () {};</script>" src="https://checkout.shopify.com/2192362/sandbox/google_analytics_iframe" onload="this.setAttribute('data-loaded', true)" sandbox="allow-scripts" id="google-analytics-sandbox" tabindex="-1" class="visually-hidden" style="display:none" aria-hidden="true" data-loaded="true"></iframe>
This error message...
org.openqa.selenium.NoSuchElementException: Returned node (null) was not a DOM element
...implies that there was no such element found as the returned node was null or was not a DOM element.
This is still a open issue with htmlunit-driver team.
However there are certain things which you need to take care as follows:
First and foremost, all the modern browsers come with built-in support for JavaScript.
HtmlUnitDriver is a WebDriver compatible driver for HtmlUnit headless browser. It has fairly good JavaScript support (which is constantly improving) and is able to work even with quite complex AJAX libraries, simulating Chrome, Firefox or Internet Explorer depending on the configuration used. So ideally while working with HtmlUnitDriver, JavaScript must be enabled, else HtmlUnitDriver may not ne able to detect the JavaScript based elements.
You can find a detailed discussion in HtmlUnitDriver does not load javascript when navigating a page from an url
The element seems to be a credit card field and historically Credit Card Number, etc resides within <iframes>.
You can find a detailed discussion in Unable to locate element of credit card number using selenium python
Whenever an <iframe> is in play src attribute of the <iframe> tag plays a vital role.
You can find a detailed discussion in Ways to deal with #document under iframe
As per best practices while switching <iframe> you need to induce WebDriverWait for the desired frame to be available and switch to it.
We have discussed this aspect in your previous question Selenium can't locate iframe
So you can use either of the following solutions:
cssSelector:
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("iframe.card-fields-iframe[id^='card-fields-number-'][src*='shopifycs']")));
xpath:
new WebDriverWait(driver, 10).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[#class='card-fields-iframe' and starts-with(#id,'card-fields-number-')][contains(#src, 'shopifycs')]")));
Update
See the snapshot of the CssSelector which identifies the element perfecto as per the HTML you have provided:
Just try with frame indexing "//iframe[index]", where index integer.
e.g. xpath : //iframe[1]
Frame id may change dynamically but in a few application structure remains same so indexing solves the problem.
Please let me know if it solves the issue.
As the iframe has tag iframe, you can switch to the iframe using the tagname like:
driver.switchTo().frame(driver.findElement(By.tagName("iframe")));
And if you want to again switch to the default content, then you can use driver.switchTo().defaultContent();

how to find xpath in selenium webdriver

Following is the HTML of the page, How do i get the Xpath or is there anyother way to automate using java?In fact, we shud click on this "continue" button.
<regform-button>
<button ng-disabled="activityIndicator" ng-click="validate()" type="button">
<div template="api-loader" ng-http-loader="">
<div class="http-loader__wrapper ng-hide" ng-show="showLoader" ng-include="template">
<span class="api-loader"></span>
</div>
</div>
<ng-transclude>
</button>
</regform-button>
If you are using Google Chrome, right click on the button, and select Inspect in the popup. The html will open in a developer tools frame. Right click on the element in the developer tools frame, hover over copy, select copy xpath.
Here is the XPath to the form on the URL.
//*[#id="main-frame"]/div[1]/div[2]/div/div[1]/div[1]/form/regform-steps/ng-transclude/regform-step[1]/ng-form/ng-transclude/regform-button/button
WebDriver driver = new ChromeDriver();
driver.get("https://uk.match.com/unlogged/landing/2016/06/02/hpv-belowthefold-3steps-geo-psc-bowling?klid=6740");
//fill in fields
WebElement element = driver.findElement(By.xpath("//*[#id=\"main-frame\"]/div[1]/div[2]/div/div[1]/div[1]/form/regform-steps/ng-transclude/regform-step[1]/ng-form/ng-transclude/regform-button/button"));
element.click();
driver.findElement(By.xpath("//regform-button/button")).click();
Try opening the console for Google Chrome and typing the following:
document.evaluate("//regform-button/button", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click()
It works...that's if you've specified the required fields. Also be sure to wait for a while (2 secs to be sure) after specifying the required fields as there might be an additional load after setting the required fields.
Edit: The code is javascript..I just took the xpath given by the previous answers and used that to locate the element through js. I'm saying that "//regform-button/button" should work..
Once you have selected the required values from the drop-downs appearing before Continue button, you can click on Continue button using the following statement:
driver.findElement(By.xpath("//span[text()='Continue']")).click();
The following xpath worked for me.But I dont know, why is it different for each different browser.
For Firefox :
`driver.findElement(By.xpath("//*[#id='main-frame']/div[1]/div[2]/div/div[1]/div[1]/form/regform-steps/ng-transclude/regform-step[1]/ng-form/ng-transclude/regform-button/button")).click()`;
For chrome: driver.findElement(By.xpath("//regform-button/button")).click();

Interrupting a file upload via Selenium using Java?

I'm trying to interrupt a file upload which doesn't seem possible. It seems that nothing gets executed beyond elem.sendKeys("filename.txt") until the entire file is uploaded. Further, none of the buttons are clickable although available when checked via Firebug or testing manually.
Automating the file upload and the interrupt by clicking a cancel file upload button (which is clickable when doing the test manually) leads to a test failure with the following exception: ElementNotVisibleException: Element is not currently visible and so may not be interacted with.
Is there any way I can enforce the interrupt? are there any other means that aids doing the same exact thing?. I'm using Firefox for this test.
HTML:
<div style="padding-left: 40px;">
<input id="upload" type="file" multiple="" label="File" name="upload[]" size="50">
</div>
Java:
WebElement elem = driver.findElement(By.id("upload"));
elem.sendKeys("filename.txt");
driver.navigate().refresh();
System.out.println("hi");
I have failed to see a point in doing that, but here we go:
I believe u can't stop the elem.sendKeys() method in Selenium(which does the actual upload).
Using it on a input text to set a string is the same as actually uploading a file. It's just Selenium trying to set some values on your input.
One way around would be clicking on a cancel upload button you have implemented.
Since you have tried that, this exception ElementNotVisibleException: Element is not currently visible and so may not be interacted with means exactly the that element exists (Selenium have found it on the DOM) but its not visible (the element has some properties like overflow: hidden display:none etc)
My best guess is that you should work that out and try clicking your button that implements an action of stopping the upload.

Responsive ul image list not breaking to new line

On the portfolio section of my site I have a ul of image screenshots of sites I have made. The main div is set to min-width: 700px and views fine in a web browsers. However on mobile/tablet the last img in the ul does not move to a new line and is instead cut off.
Can someone please advise on the best css rule to apply or if I should restructure the ul completely.
View the issue here: portfolio
Remove the white-space: nowrap property for #container1, #container2, #container3, #container4.
The images do not move to the next line because of nowrap.

Categories

Resources