Block an unexpected popup with Selenium - java

I am automating an e-commerce website but I am getting an unexpected random popup on any page. If I know that a popup will fire on a given web page, I can handle it. What do I do if it randomly occurs on any page?
I know how to block a popup but can't use that in this situation. Due to this popup, my scripts are failing. HTML code:
<div class="acsClassicInner" role="document">
<div class="acsLogoSpacer">
<img src="//gateway.foresee.com/sites/barneys/staging/trigger/sitelogo.gif" class="acsSiteLogo" title="" alt="">
<img src="https://static.foresee.com/logos/foresee/150_67.png" class="acsNoDisplay" title="ForeSee" alt="ForeSee">
<div title="ForeSee" alt="ForeSee" class="acsVendorLogoSVG"></div>
</div>
<h1 id="fsrHeading">We'd welcome your feedback!</h1>
<p>Thank you for visiting Barneys.com. You have been selected to participate in a brief customer satisfaction survey to let us know how we can improve your experience.</p>
<p class="acsNoticeAboutSurvey">The survey is designed to measure your entire experience, please look for it at the <u>conclusion</u> of your visit.</p>
<p class="acsAttribution">This survey is conducted by an independent company ForeSee, on behalf of the site you are visiting.</p>
No, thanks
<a id="acsFocusFirst" tabindex="3" href="about:blank" target="_blank" class="acsInviteButton acsRightButton acsAcceptButton" title="Yes, I'll give feedback (Opens in a new window)" role="button" precog_scanned="true">Yes, I'll give feedback</a>
</div>

Look into EventFiringWebDriver and WebDriverEventListener, and look for the popup in question> lets say the popup occurs after a button click, you can look for it in beforeClickOn and if it does occur do an action, else don't do anything.
Sorry I dont have any Java EventFiringWebDriver code snippets to share
http://seleniumhq.github.io/selenium/docs/api/java/index.html
code from selenium github
from selenium.webdriver import Firefox
from selenium.webdriver.support.events import EventFiringWebDriver, AbstractEventListener
class MyListener(AbstractEventListener):
def before_navigate_to(self, url, driver):
print("Before navigate to %s" % url)
def after_navigate_to(self, url, driver):
print("After navigate to %s" % url)
driver = Firefox()
ef_driver = EventFiringWebDriver(driver, MyListener())
ef_driver.get("http://www.google.co.in/")

Create a helping method with the following pseudo code:-
1. Check if there's a pop up.
2. If it finds pop up, then handle it.
3. If not, then return.
Now use this function in your script every time whenever there's a change in the content on the screen due to some action.

Related

Keys.RETURN and Keys.ENTER not triggering form submission

I havent been able to select the element in googles popup form that will let me submit the form so i opted to use Keys.TAB and Keys.ENTER but it doesnt trigger submission. if i do it manually it works but my code just highlights the button and presses ENTER with no success.
popup window image
driver.findElement(By.xpath(someElement)).sendKeys(Keys.TAB);
Thread.currentThread().sleep(1000);
driver.findElement(By.xpath(someElement)).sendKeys(Keys.TAB);
Thread.currentThread().sleep(1000);
driver.findElement(By.xpath(someElement)).sendKeys(Keys.ENTER);
I added a pause between each key press because i read on here that it can be an issue but it hasnt solved my problems. for perspective the form im trying to submit is the google search console URL removal confirmation and the div surrounding the button looks like this:
<div role="button" class="U26fgb O0WRkf oG5Srb C0oVfc kHssdc sZloWc M9Bg4d" jscontroller="VXdfxd" jsaction="click:cOuCgd; mousedown:UX7yZ; mouseup:lbsD7e; mouseenter:tfO1Yc; mouseleave:JywGue; focus:AHmuwe; blur:O22p3e; contextmenu:mg9Pef;touchstart:p6p2H; touchmove:FwuNnf; touchend:yfqBxc(preventMouseEvents=true|preventDefault=true); touchcancel:JMtRjd;"
jsshadow="" jsname="LgbsSe" aria-disabled="false" tabindex="0" data-id="EBS5u">
<div class="Vwe4Vb MbhUzd" jsname="ksKsZd"></div>
<div class="ZFr60d CeoRYc"></div><span jsslot="" class="CwaK9"><span class="RveJvd snByac">Submit request</span></span>
</div>
I've been racking my brain trying to access this last button, some help would be much appreciated. is there a better way to go about this? or have i missed something important in the form to allow me to access the submit button

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.

javaFX 8 - How to get the link I click on, inside a WebView

I got my first JavaFX 8 application with 2 WebViews.
The WebView on the left is made of a Table of Contents made in HTML that looks like that :
<div id="toc" class="toc">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel0">
<li>1 INTRODUCTION</li>
<!-- other lines like the one just above -->
</ul>
</div>
</div>
And the WebView on the right loads a HTML file. If I load it with "#_1_introduction" at the end of it's path, it will directly go on the introduction.
The thing is that I don't know how to get the "href" thing from the WebView on the left when the user clicks on it.
So my question is : "How do I get the string in the href line when a user clicks on it ?"
Thank you :)
Edit : I tried the code in HyperlinkListener in JavaFX WebEngine but it doesn't work, I mean, I don't even know what to import to make it work ;(

How to get PJAX to work on a button and a link?

I have a number of buttons like this:
<button data-pjax class="btn btn-inverse" type="button" onclick="location.href='http://mybuttonurl.com'">my button</button>
And a number of urls like this:
<a data-pjax href="http://mylinkurl.com">My url</a>
I want PJAX to work on both the buttons and the links. This code works for the links:
$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-content');
So does this:
$(document).pjax('a', '#pjax-content');
I can't seem to get it working for buttons and links. Even this won't work for buttons alone:
$(document).pjax('button', '#pjax-content');
How can I get this to work?
Note: when I say "won't work" it means the page does a full refresh rather than just load the HTML content into #pjax-content.
As I am using Twitter Bootstrap I ended up replacing the button with a link:
<a data-pjax class="btn btn-inverse" type="button" href='http://mybuttonurl.com'>my button</a>
I believe this is a better way to do what I was trying to do + PJAX works cross browser this way

Parsing HTML with xpath or cssSelector?

How do I parse for just the text portions of these blocks of code? I am using Selenium client drivers in java.
<li id="NOT_PUT_PREF_STORE" style="">
<span id="STORE_AVAIL" class="BodyLBoldGrey StockStat">Out of stock</span> <span id="InYourLocal">in your local</span> <span id="storeRollover_2"><span id="STORE_CITY" class="BodyLBoldLtgry VIBSStore1">West Hills</span></span> store<span id="notSelectOptionSOI">.</span>
</li>
or
<li id="NOT_PUT_PREF_STORE" style="">
<span id="STORE_AVAIL" class="BodyLLtgry StockStat">Not carried</span> <span class="BodyLLtgry" id="InYourLocal">in your local</span> <span id="storeRollover_2"><span id="STORE_CITY" class="BodyLBoldLtgry VIBSStore1">West Hills</span></span> store<span id="notSelectOptionSOI">.</span>
</li>
or
<li id="NOT_PUT_PREF_STORE" style="">
<span id="STORE_AVAIL" class="BodyMBold StockStatGreen">In stock</span> <span id="InYourLocal">in your local</span> <span id="storeRollover_2"><span id="STORE_CITY" class="BodyLBoldLtgry VIBSStore1">West Hills</span></span> store<span id="notSelectOptionSOI">.</span>
</li>
I am trying to parse for the text portion in each of these variations in the webelement (ie: Not carried, In stock, Out of stock). I am a very new user to selenium and html parsing so this is really hard for me to get functional.
I was thinking that it would be something like
WebElement driver = new FirefoxDriver(profile);
driver.get(Url);
System.out.println(driver.getElement(By.id("STORE_AVAIL").getText());
Not sure how I would do it with cssSelector but people tell me that is faster.
Would this work?
driver.getElement(By.xpath("//li[#id='NOT_PUT_PREF_STORE']./span[#id='STORE_AVAIL']").getText()
When I try to find elements on the page I always build my locators by:
id = driver.getElement(By.id("STORE_AVAIL").getText());
css selector = driver.getElement(By.css("span#STORE_AVAIL").getText());
xpath = driver.getElement(By.xpath("//span[#id='STORE_AVAIL']").getText());
The id seems to be the fastest and easiest, both for webdriver and for me. id should be unique on the page.
CSS take a little more investigative work on my part, but webdriver handles it just fine.
Lastly, xpath is sometimes unavoidable (unless you buy the devs a beer and ask nicely to change to application so you can locate it faster - after all, you are testing for them anyway). Locating by xpath with IE is terribly slow and writing complex xpaths is a drag.
Xpath is also fragile, one small change to the dom can render your xpath unusable. Then you get to debug/rewrite your xpath (it is as fun as it sounds).
My suggestion is to use Firebug and FirePath addons for Firefox to help you craft your locators.
When you 'View Page Source' it will only show the original HTML source. It will not show changes made by AJAX calls, which looks like how the Walmart page is updating that section/element. This question provides a better explanation.
Assuming you are using Firefox (based on the driver you are using), you can go to the page and click Ctrl+Shift+I to bring up the Inspector tool. Select the element you are interested in. Then click the [HTML] button (in the Inspector menu) to view the current source.
Note that when you are getting the element using selenium webdriver, it will be getting the current value rather than the original value seen in the page source. So you do not have to worry about what you see in the page source.
I am tried with the following html code snipet
<li id="NOT_PUT_PREF_STORE" style="">
<span id="STORE_AVAIL" class="BodyLBoldGrey StockStat">Out of stock</span> <span id="InYourLocal">in your local</span> <span id="storeRollover_2"><span id="STORE_CITY" class="BodyLBoldLtgry VIBSStore1">West Hills</span></span> store<span id="notSelectOptionSOI">.</span>
</li>
I am using the following code to solve it. I get the tree of span elements using XPath and parse through each of it to get the text of the elements.
driver.navigate().to("file:///C:/Users/abc/Desktop/test.html");
List<WebElement> spanEle = driver.findElements(By.xpath("//li/span"));
for (int i = 0; i < spanEle.size(); i++) {
System.out.println(spanEle.get(i).getText());

Categories

Resources