WebDriver does not return to default content - python

I'm trying to write a test for a pair of sites taking part in the online support system: one is for Agent, the second is for the Visitor.
Initially, the Visitor opens the support tab on his site and the Agent gets the call on his side and picks it up. Both sides get the text chat only at this moment.
After that, the Agent wants to escalate the chat-call to Audio-Video level and presses a special button for that.
An additional widget opens containing the IFRAME element with INVITE button.
Agent presses the INVITE button.
After that the Agent has to press the Send button in the textual chat (that is on the main page content, not in the IFRAME) to send the invitation for the agent to join the Audio-Video chat.
These are the steps that I want to automate.
Everything is working until the .switch_to_default_content(). After that, the browser seems to lose the DOM and does not find neither elements on the main page nor inside the IFRAME.
Behavior is the same for local WebDriver and for WebDriver.Remote grid, for Chrome latest and Firefox latest, on Windows 10 and on Mac OS X 10.11.6 regardless of Capabilities combination.
Below is the code in Pytnon:
#Starting the Agent browser
options = webdriver.ChromeOptions()
options.add_argument("--disable-notifications")
agent_browser = webdriver.Remote(command_executor='http://127.0.0.1:4444/wd/hub', desired_capabilities=options.to_capabilities())
<...>
#Starting the Visitor browser
visitor_browser = webdriver.Remote(command_executor='http://127.0.0.1:4444/wd/hub', desired_capabilities=DesiredCapabilities.CHROME)
<...>
# Finding the IFRAME
agent_LPVE_iframe = WebDriverWait(agent_browser, 30).until(EC.presence_of_element_located((By.XPATH, "//iframe[contains(#class, 'lpview_table_items_placeholder')]")))
# Switching to IFRAME
agent_browser.switch_to_frame(agent_LPVE_iframe)
<...>
# Switching to default contents
#agent_browser.switch_to_default_content()
agent_browser.switch_to.default_content()
After this, the WebDriver becomes unable to find any element in both main page DOM and inside the IFRAME even if it gets switched back to IFRAME.
Why it happens and how do I make it work correctly?
I am using:
- Python 3.6.0 x32
- selenium-server-standalone-3.3.1.jar
- ChromeDriver 2.28 Win32
- GeckoDriver 0.14.0 x64
Tell me if you need any additional information.

Related

SendKeys does not work when computer is locked using Selenium

I use python 3.9.5 and selenium 4.1.0 with Microsoft Edge 98.0.1108.43 on Windows 10 to fill a date in a text box with the code below:
#element is the web element I want to fill
element = "element_name"
date = driver.find_element(By.ID, element)
date.click()
date.clear()
#Positionate cursor at text box beginning
for i in range(1,10):
date.send_keys(Keys.ARROW_LEFT)
#Fill the date
date.send_keys("11022022")
I use a Windows task scheduler to run a python script when the computer is locked.
This code uses to work when I am logged in and using the computer, but when it's locked the send keys fail, it used to work with edge version 95, but in recent versions stopped.
Unfortunately, I can't simply replace the value of the element, apparently, the site has some different mechanism to fill it and I must fill it with the keyboard.
<input name="element_name" type="text" value="04/02/2022" id="ctl00_ContentPlaceHolder1_dtInicial_txtData" class="edt" style="width:90px;">
I also have tried to force windows to always focus on browser windows, so the webpage always has the keyboard focus, but it also does not work.
Any hint of how to solve this question? Is it a Bug?
In Selenium there is a state that called headless, it allows you to work with the web page without actually "seeing" it. There is no window opening and everything works virtually. You set this state in the browser options.
EdgeOptions edgeOptions = new EdgeOptions();
edgeOptions.UseChromium = true;
edgeOptions.BinaryLocation =
#"C:\Program Files
(x86)\Microsoft\Edge\Application\msedge.exe";
edgeOptions.AddArgument("headless");
edgeOptions.AddArgument("disable-gpu");
var msedgedriverDir = #"E:\webdriver";
var driver =
new EdgeDriver(msedgedriverDir, edgeOptions);
In Java, there is a class called Robot which mimic keyboard pressing, so try to find the matching library in Python.

How to dynamically update Selenium methods without restarting the webdriver?

I have a Selenium bot that interacts with EA Sports FIFA 21 web app, where you can buy and sells in-game football players. The interface looks like this.
Lets say my original program was a single script that:
login() - logged into the platform
goToTransferMarket() - navigated to the ‘market search’ page
inputSearchParameters(playername) - inputted my search parameters to search
clickSearch() - clicked Search button
evaluateResults(buy_price) - evaluated results and bought players cheaper than buy price
If any method failed, I’d have to quit and restart from scratch. To fix this, I built a tkinter GUI with buttons for each function that executes in their own thread. This way If a function fails, like clicking the search button, I can manually perform the action and proceed to test the subsequent methods.
But still, to fix the broken methods, I have to restart the program from scratch which requires a tedious login process to fix something as simple as forgetting to cast a string to an integer. Logging in a lot also draws unwanted attention.
Given that I’m already logged in during the current testing session, is there a way to recompile my program and ‘grab’ the existing webdriver session?
Even better, is it possible to dynamically change my functions and update them with an ‘update with latest code’ button in my GUI?
The 'player list' box in my GUI writes to a textfile, which allows me to change who the bot is searching for in real time. The textfile is passed to the main bot search method when I click the "Bid using list" button. This is what made me wonder if I can set it up to somehow recompile parts of my code in a separate thread and keep my existing webdriver session. Any help would be amazing thank you.
You can add a infinite while loop and try catch to make sure your test never fails else :
If you are using chrome :
you can connect to existing chrome session using debuuger address, so start the chrome with specified debugging port from cmd
Start chrome with debug port: (In windows , search for other os how to start chrome in a specific debug port)
<path>\chrome.exe" --remote-debugging-port=1559
And in selenium use :
JAVA:
System.setProperty("webdriver.chrome.driver", "C:\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("debuggerAddress", "127.0.0.1:1559");
WebDriver browser=new ChromeDriver(options);`
Python :
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:1559")
driver = webdriver.Chrome(options=chrome_options)

Edge automation with Selenium - Credential required constantly

I want to open e.g. Google page with Edge using Selenium and Python inside company network.
from selenium import webdriver
browser = webdriver.Edge(r"C:/_path_to_driver_/msedgedriver.exe")
browser.get("https://www.google.com")
Edge opens this site and asks me to insert my mail.
After entering mail, it redirects me to this page:
I have to click always manually on OK. Selenium is not able to click on that OK.
Any idea how to perform a click? OR there is way how to store my mail address or certificate to not being always ask for it? This issue occurs only with the Edge controlled by selenium. Default Edge remembers all settings.
If we use selenium webdriver to automate Edge without any arguments, it will create a new profile every time instead of using the existing user data profile. That's why it asks for credential every time.
As a workaround, you can use user-data-dir and profile-directory to use specific profile to launch Edge using Selenium WebDriver. You can use the profile that stores the credential so that it won't ask for credential when you automate Edge. I think in your case it's the default Edge profile.
You need to install the MS Edge Selenium tools using command pip install msedge-selenium-tools selenium==3.141 then refer to the sample code below:
from msedge.selenium_tools import Edge, EdgeOptions
edge_options = EdgeOptions()
edge_options.use_chromium = True
#Here you set the path of the profile ending with User Data not the profile folder
edge_options.add_argument("user-data-dir=C:\\Users\\username\\AppData\\Local\\Microsoft\\Edge\\User Data");
#Here you specify the actual profile folder
edge_options.add_argument("profile-directory=Profile 2");
driver = Edge(options = edge_options, executable_path = r"C:\_path_to_driver_\msedgedriver.exe")
driver.get('https://www.google.com')
Note: Change the paths in the code to your owns.
If you don't know the path of the specific profile, you could check edge://version/ like below:

Open Application (such as zoom.us) with Selenium Webdriver

I want to be able to use pure selenium webdriver to open a zoom link in Chrome and then redirect me to the zoom.us application.
When I execute this:
from selenium import webdriver
def main():
driver = webdriver.Chrome()
driver.get("https://zoom.us/j/000-000-000")
main()
I receive a pop-up saying
https://zoom.us wants to open this application.
and I must press a button titled open zoom.us to open the app.
Is there a way to press this pop-up button through selenium. Or, is there some other way to open zoom from chromedriver?
NOTE: I only want to use selenium. I have been able to implement pyautogui to click on the button but that is not what I am looking for.
Solution for Java:
driver.switchTo().alert().accept();
Solution for Python:
driver.switch_to.alert.accept()
There are a lot of duplicated questions regarding this issue. Here is one of them, and it is quite sure that selenium is not capable of achieving such job since it only interacts with the chrome page. I previously encountered this issue as well and here is my solution to it. It might look really unprofessional, but fortunately it works.
The logic of my solution is to change the setting of chrome in order to skip the popup and directly open the application you want. However, the Chrome team has removed this feature in the latter version for some reasons, and we need to get it back manually. Then, we know that everytime when selenium starts to do the thing it opens a new Chrome page with NO customized settings just like the incognito page. Therefore we need to do something to let selenium opened a Chrome page with your customized setting, so that we can make sure that the popup, which we changed manually to skip, can be skipped successfully.
Type the following code in your terminal.
defaults write com.google.Chrome ExternalProtocolDialogShowAlwaysOpenCheckbox -bool true
This enables you to change the setting of skipping popups, which is the feature Chrome team removed.
Restart Chrome,and open the zoom (or whatever application) page to let the popup display. If you do the 1st step correctly you will be able to see there is a checkbox shown next to the "Open Zoom.us" saying if you check it chrome will open this application without asking, that is, to skip the popup for this application.
Now we need to let selenium open the Chrome with our customized setting. To do this, type "chrome://version" in the search tab of your ordinary Chrome (Not automated page opened by selenium). Go to "Profile Path", and copy this path without the last word "default". For example:
/Users/MYNAME/Library/Application Support/Google/Chrome/Default
This is my profile path, but I only copy everything except the last word Default, so this is what I need to copy.
/Users/MYNAME/Library/Application Support/Google/Chrome/
This is for Mac users, but for Windows only the path is different(starts with C:// or something), steps are same.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
option = Options()
option.add_argument('THE PATH YOU JUST COPIED')
driver = webdriver.Chrome(executable_path='YOUR PATH TO CHROMEDRIVER', options=option)
driver.get("google.com") #Or anything else
We use "options" to let selenium open a page with our customized profile. Now you will see selenium opens a Chrome page with all your account profile, settings, and it just appears like your ordinary chrome page.
Run your code. But before that, remember to quit ALL CHROME sessions manually. For Mac, make sure that there is no dot under Chrome icon indicating that Chrome is not running for any circumstances. THIS STEP IS CRITICAL otherwise selenium will open a chrome page and it just stops there.
Here are all the steps. Again, this solution is vert informal and I personally don't think it is a "solution" to this problem. I will try to figure out a better way of achieving this in the future. But I still posted this as an alternative simply because I guess it might be helpful to some extent for somebody just like me. Hope it works for you, and good luck.

Selenium action chains to click inside silverlight plugin object in a page

Currently trying to click a button inside of a silverlight web app, and yes I know beforehand silverlight is not supported but I think at least it worth a try with the action chain module. Here is the best I could come up with until now:
profile = FirefoxProfile()
profile.set_preference('plugin.default.state', 2)
driver = webdriver.Firefox(profile)
driver.get('http://www.trypython.org')
time.sleep(8)
sldiv = driver.find_element_by_xpath('//*[#id="silverlightControlHost"]')
builder = ActionChains(driver)
builder.move_to_element_with_offset(sldiv, 372, 44)
builder.click()
IT is not clicking, or at least not in the expected coordinates (where the button is). Will I get away with this? if so, will I be able to type some text after clicking inside a textbox?
Do not even mention silverlight-selenium outdated project

Categories