Python 3 Selenium - select dynamically generated iframe without a name - python-3.x

(Working with Python 3 and Selenium. Trying to interact with Buffer.com's alert window after pressing "Shuffle" link.)
After pressing a button on the main browser frame, an alert pops up with two buttons. I want to press one of them.
I am trying to change the focus to this iframe that contains the alert, but I can't see it to have a name. Here's the code of said alert iframe:
<iframe src="https://js.stripe.com/v2/m/outer.html#referrer=https%3A%2F%2Fbuffer.com%2Fsignin&title=Buffer&url=https%3A%2F%2Fbuffer.com%2Fapp%2Fprofile%2F55e5cd556321154607cc5244%2Fbuffer%2Fqueue%2Flist&muid=c7aa769e-c41c-4e86-b75f-99771764f6a5&sid=26221bdc-c091-42c2-8965-8ea3e84267e2&preview=false&" frameborder="0" allowtransparency="true" scrolling="no" tabindex="-1" aria-hidden="true" style="width: 1px !important; height: 1px !important; position: fixed !important; visibility: hidden !important; pointer-events: none !important;"></iframe>
The element CONTAINING this iframe, in turn, has a name, but it is dynamically generated. The code of the upper level iframe containing the iframe I want is:
<iframe name="stripeXDM_default441361_provider" id="stripeXDM_default441361_provider" aria-hidden="true" src="https://js.stripe.com/v2/channel.html?stripe_xdm_e=https%3A%2F%2Fbuffer.com&stripe_xdm_c=default441361&stripe_xdm_p=1#__stripe_transport__" frameborder="0" style="position: absolute; top: -2000px; left: 0px;"></iframe>
The "stripeXDM_default441361_provider" is dynamic and changes every time the alert pops up.
I have tried switch_to.frame but could not get it right.
I also tried to select the dynamically-generated iframe with "Xpath containing" but did not work either.
Any suggestions on how I can select this iframe with no name?

To select the iframe, you could use the xpath. For example, if we consider this html:
<!DOCTYPE html>
<html>
<body>
<span id="n2">
<span id="n6">
<a class="cn" name= "A1" >One</a>
</span>
<span id="n7">
<a class="cn" name= "A2" >Two</a>
</span>
<span id="n8">
<a class="cn" name= "A3" >Three</a>
</span>
</span>
</body>
</html>
You can do this:
driver.find_element_by_xpath(("//span[#id='n2']/span[#id='n6']/a[#name='A1' and text()='One']"))
to identify the element with name 'A1' and text 'One'.
But also:
driver.find_element_by_xpath(("//span/span[1]/a[#name='A1' and text()='One']"))
So, in your case you can find the "external" iframe element and after the "internal" one (I assumed there aren't other iframe). Something like this:
//iframe/iframe
After you select the iframe you have to switch to it.

It turns out I was overcomplicating things. I did not need to change focus or anything else.
I just assume that it was all html and I tried to select the element directly with xpath, like so:
#do something
#press shuffle button
#once the button appears in the iframe, blurring everything else, use this line:
button = browser.find_element_by_xpath('//*[#id="modal-buttons"]/a[2]')
button.click()
That's what I did and worked perfectly.

Related

Instead of left click on a link I find I must right click. Why? Is this a new feature or a bit of code that went wrong?

I am facing an issue with slider button link, when I right-click on button it's working fine but not on left-click. I have tried many things, yet do not find any solution.
here is button code:
<a class="wow bounceInUp" data-wow-offset="10" href="https://www.google.com" style="visibility: visible; animation-name: bounceInUp;">Shop Now</a>
I put your button code into a codepen. It does seem to work for me. make sure to start and end your button with <a> </a>
<a class="wow bounceInUp" data-wow-offset="10" href="https://www.google.com" style="visibility: visible; animation-name: bounceInUp;">Shop Now</a>
https://codepen.io/Leeroy-J/pen/podVRvy

CSS selector for reCAPTCHA checkbok using Selenium and VBA Excel

On the website I am trying to fill in some fields on, there is a checkbox that I need to click to add the check mark in it:
<div class="rc-anchor-content"><div class="rc-inline-block"><div class="rc-anchor-center-container"><div class="rc-anchor-center-item rc-anchor-checkbox-holder"><span class="recaptcha-checkbox goog-inline-block recaptcha-checkbox-unchecked rc-anchor-checkbox recaptcha-checkbox-expired" role="checkbox" aria-checked="false" id="recaptcha-anchor" dir="ltr" aria-labelledby="recaptcha-anchor-label" aria-disabled="false" tabindex="0"><div class="recaptcha-checkbox-border" role="presentation" style=""></div><div class="recaptcha-checkbox-borderAnimation" role="presentation" style=""></div><div class="recaptcha-checkbox-spinner" role="presentation" style="transform: rotate(180deg);"></div><div class="recaptcha-checkbox-spinnerAnimation" role="presentation" style=""></div><div class="recaptcha-checkbox-checkmark" role="presentation"></div></span></div></div></div><div class="rc-inline-block"><div class="rc-anchor-center-container"><label class="rc-anchor-center-item rc-anchor-checkbox-label" aria-hidden="true" role="presentation" id="recaptcha-anchor-label"><span aria-live="polite" aria-labelledby="recaptcha-accessible-status"></span>I'm not a robot</label></div></div></div>
Using Selenium in VBA, I tried the following
.FindElementByCss("div.recaptcha-checkbox-border").Click
And also I tried
.FindElementByCss("span.recaptcha-checkbox").Click
But I got an error at this line.
Here's the link of the website to see the whole HTML
https://www.moj.gov.kw/AR/E-Gov/Pages/eServices01.aspx
To click() on the element, as the desired element is within an <iframe> so you have to:
Induce a waiter and switch to the desired frame.
Induce a waiter for the desired element to be clickable.
You can use the following solution:
.SwitchToFrame.FindElementByXPath("//iframe[contains(#src, 'recaptcha') and not(#title='recaptcha challenge')]", timeout:=10000)
.FindElementByCss("div.recaptcha-checkbox-checkmark").Click
You can find similar discussions in:
How to click on the reCaptcha using Selenium and Java
Find the reCAPTCHA element and click on it — Python + Selenium
Here you can find a relevant discussion on Ways to deal with #document under iframe

2 iframes with the same display even if the src are different

I am using this code:
<div class="infobox-pair">
<div class="ibp-left">
<iframe width="105" height="350" frameborder="0" scrolling="no" style="width: 311px; height: 105px;" marginwidth="0" marginheight="0" name="infobox_flight" id="ibp-left-iframe" src="http://mywebpage.com/paris"></iframe>
</div>
<div class="ibp-right">
<iframe width="105" height="350" frameborder="0" scrolling="no" style="width: 311px; height: 105px;" marginwidth="0" marginheight="0" name="infobox_package" id="ibp-right-iframe" src="http://mywebpage.com/lisbonne"></iframe>
</div>
That is displaying into the same div two different iframes. When I display the page whatever the browser it happens that I can get the same content for both the iframes even if looking at the source code the iframe are still different (based on their src and id).
It doesn't happen 100% of the time, I have to refresh sometimes several times to see it.
Do you have any clue ?
Thanks in advance
One thing to keep in mind, when you refresh in IE and some other browsers, the browser will retain the "current" src="" value for iframe, so if you navigated around a bit in the iframes, then hit F5, the current last navigated path for each iframe is still in the iframes. Is it possible you navigated to the same page somehow?
The only reliable way to get the iframes to "Reset" back to their initial src values on a refresh(f5) is to use javascript to set their src as a part of the page load event. I recommend setting the initial src in markup to just "about:blank" and alwyas programatically change it.
This has been a long time answered but have some additional info that might help web developers.
If you have loaded iFrame 1 in the browser before, then the newly added iFrame 2 will show the same content, even after refreshing multiple times. Try hitting Ctrl + F5, or clearing your temp files in browser, this can reset the iFrame src to it's correct value.

Sharepoint Theme specific image

In my Sharepoint masterpage I have added an <img> to the top of the <body> of the page so that I can use some CSS to set the <img> to fill the screen.
However I want a different image to be displayed depending on the theme in use. I currently use the following inside the masterpage:
<img alt="" id="fullscreen" src="/_layouts/images/Background.png" />
Is it possible to capture the name of the theme in use and append that to the file name so I can simple adjust file names to match there theme?
Or failing that can I add something to src=" " that will make the URL theme specific?
I think the idea is to reference the images from your theme CSS. So if an image changes between themes, the url to that image is stored in each of the theme CSS files.
You master page can then simply contain an element with always the same CSS class.
What about defaulting the images to hidden, and in the CSS for the theme you want it shown in, show it?
For example:
In your master page:
<img src="theme1.jpg" alt="" id="theme1fullscreen" style="display: hidden;" />
<img src="theme2.jpg" alt="" id="theme2fullscreen" style="display: hidden;" />
<img src="theme3.jpg" alt="" id="theme3fullscreen" style="display: hidden;" />
In the css for Theme X:
#themeXfullscreen {
display: block;
height: 100%;
width: 100%;
}
This way, you have the images and locations in the master page, and can hide and show the appropriate one based on the theme.

JSF Upload component: alternate triggering

I have a JSF form that needs to upload a file via an icon click (i.e. without showing the textfield/browse button of the file upload component).
Is it possible to trigger the file-open dialog and uploading functionality of the upload component via some other component type?
No, the file upload dialog is meant to be pretty much unchangeable as a security feature.
I don't think there's any other "off the shelf" component you could use to trigger the file-open dialog (which, after all, results from a <input type=file> written by the renderer).
However, if you're willing to develop your own renderer, it could write both the <input> and your icon's <img> (one right after the other). Give the <input> a css class that uses absolute positioning to place it on top of the <img> and reduces it's opacity to 0 (you could also set the cursor to 'pointer').
Now, when the user clicks on the icon, they're also clicking on the invisible input, which pops up your dialog.
(Now that I think of it, I'm almost positive you can do this without writing your own renderer by just applying the same kind of css to off the shelf components...)
With HTML5, there is new way to styling the css with bootstrap for example and replace image by a glyphicon.
.btn-file {
position: relative;
overflow: hidden;
}
.btn-file input[type=file] {
filter: alpha(opacity=0);
opacity: 0;
outline: none;
cursor: inherit;
display: block;
width:32px;
font-size:24pt;
height:12px;
}
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<form>
<span class="btn btn-default btn-file btn-lg">
<span class="glyphicon glyphicon-upload"> </span> <input type="file">
</span>
</form>
</body>
</html>

Resources