Python-selenium action chains not working in Safari - angularjs

I am trying to click on a menu and then a submenu in selenium-python on a Safari Webdriver. No matter what I do, I cannot seem to make the ActionChains do anything whatsoever. Am I doing something wrong or is this an issue with Safari?
I have tried a number of different actions using the ActionsChain, but none of them seem to be working
```driver = webdriver.Safari()
wait = WebDriverWait(driver, 20)
url = "someurl.com"
link_text = "link text"
driver.get(url)
driver.maximize_window()
wait.until(EC.element_to_be_clickable((By.LINK_TEXT, link_text)))
ActionChains(driver).move_to_element(driver.find_element(By.LINK_TEXT, link_text)).click().perform()
print('Hello World')```
I expect to see the browser clicking on the element, but I see only the terminal of my program printing 'Hello World'.

You could try clicking with JavaScript instead of ActionChains here:
element_to_click = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, link_text)))
driver.execute_script(“arguments[0].click();”, element_to_click)

Related

Python Selenium Failing to Acquire data

I am trying to download the 24-month data from www1.nseindia.com and it fails on Chrome and Firefox drivers. It just freezes after filling all the values in the required places and does not click. The webpage does not respond...
Below is the code that I am trying to execute:
import time
from selenium import webdriver
from selenium.webdriver.support.ui import Select
id_list = ['ACC', 'ADANIENT']
# Chrome
def EOD_data_Chrome():
driver = webdriver.Chrome(executable_path="C:\Py388\Test\chromedriver.exe")
driver.get('https://www1.nseindia.com/products/content/equities/equities/eq_security.htm')
s1= Select(driver.find_element_by_id('dataType'))
s1.select_by_value('priceVolume')
s2= Select(driver.find_element_by_id('series'))
s2.select_by_value('EQ')
s3= Select(driver.find_element_by_id('dateRange'))
s3.select_by_value('24month')
driver.find_element_by_name("symbol").send_keys("ACC")
driver.find_element_by_id("get").click()
time.sleep(9)
s6 = Select(driver.find_element_by_class_name("download-data-link"))
s6.click()
# FireFox(Gecko)
def EOD_data_Gecko():
driver = webdriver.Firefox(executable_path="C:\Py388\Test\geckodriver.exe")
driver.get('https://www1.nseindia.com/products/content/equities/equities/eq_security.htm')
s1= Select(driver.find_element_by_id('dataType'))
s1.select_by_value('priceVolume')
s2= Select(driver.find_element_by_id('series'))
s2.select_by_value('EQ')
s3= Select(driver.find_element_by_id('dateRange'))
s3.select_by_value('24month')
driver.find_element_by_name("symbol").send_keys("ACC")
driver.find_element_by_id("get").click()
time.sleep(9)
s6 = Select(driver.find_element_by_class_name("download-data-link"))
s6.click()
EOD_data_Gecko()
# Change the above final line to "EOD_data_Chrome()" and still it just remains stuck...
Kindly help with what is missing in that code to download the 24-month data... When I perform the same in a normal browser, with manual clicks, it is successful...
When you are manually doing it in a browser, you can change the values as below:
Set first drop down to : Security wise price volume data
"Enter Symbol" : ACC
"Select Series" : EQ
"Period" (radio button: "For Past") : 24 Months
Then click on the button, "Get Data", and in about 3-5seconds, the data loads, and then when you click on "Download file in CSV format", you can have the CSV file in your downloads
Need help using any library you know for scraping in Python: Selenium, Beautifulsoup, Requests, Scrappy, etc... Doesn't really matters unless it is python...
Edit: #Patrick Bormann, pls find the screenshot... The get data button works..
When you say that it works manually, have you try to simulate a click with action chains instead of the internal click function
from selenium.webdriver.common.action_chains import ActionChains
easy_apply = Select(driver.find_element_by_id('dateRange'))
actions = ActionChains(driver)
actions.move_to_element(easy_apply)
actions.click(easy_apply)
actions.perform()
and then you simulate a mouse movement to the specific value?
In addition, I tried it on my own and I didnt get any data when pushing on the button Get Data, as it seems to have a class of "get" as you mentioned, but this button doesnt work, but as you can see there exists a second button called full download, perhaps ypu try to use this one? Because the GetData Button doesnt work on Firefox and Chrome (when i tested it).
Did you already try to catch it through the link?
Update
As the OP asks for help in this urgent matter I delivered a working solution.
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
from selenium.webdriver.support.ui import Select
chrome_driver_path = "../chromedriver.exe"
driver = webdriver.Chrome(executable_path=chrome_driver_path)
driver.get('https://www1.nseindia.com/products/content/equities/equities/eq_security.htm')
driver.execute_script("document.body.style.zoom='zoom 25%'")
time.sleep(2)
price_volume = driver.find_element_by_xpath('//*[#id="dataType"]/option[2]').click()
time.sleep(2)
date_range = driver.find_element_by_xpath('//*[#id="dateRange"]/option[8]').click()
time.sleep(2)
series = driver.find_element_by_name('series')
time.sleep(2)
drop = Select(series)
drop.select_by_value("EQ")
time.sleep(2)
driver.find_element_by_name("symbol").send_keys("ACC")
ez_download = driver.find_element_by_xpath('//*[#id="wrapper_btm"]/div[1]/div[3]/a')
actions = ActionChains(driver)
actions.move_to_element(ez_download)
actions.click(ez_download)
actions.perform()
Here you go, sorry, took a little, had to bring my son to bed...
This solution provides this output: I hope its correct. If you want to select other drop down menus you can change the string in the select (string because of too much indezes too handle) or the number in the xpath as the number highlights the index. The time is normally only for elements which need time to build themselves up on a webpage. But I made the experience that a too fast change sometimes causes errors. Feel free to change the time limit and see if it still works.
I hope you can now go on again in making some money for your living in India.
All the best Patrick,
Do not hesitate to ask if you have any questions.
UPDATE2
After one long night and another day we figured out that the Freezing originates from the website, as the website uses:
Boomerang | Akamai Developer developer.akamai.com/tools/… Boomerangis
a JavaScript library forReal User Monitoring (commonly called RUM).
Boomerang measures the performance characteristics of real-world page
loads and interactions. The documentation on this page is for mPulse’s
Boomerang. General API documentation for Boomerang can be found
atdocs.soasta.com/boomerang-api/.
.
What I discovered from the html header.
This is clearly a bot detection network/javascript. With the help of this SO post:
Can a website detect when you are using Selenium with chromedriver?
And the second paragraph from that post:https://piprogramming.org/articles/How-to-make-Selenium-undetectable-and-stealth--7-Ways-to-hide-your-Bot-Automation-from-Detection-0000000017.html
I finally solved the issue:
we changed the
var_key in chromedriver to something else like:
var key = '$dsjfgsdhfdshfsdiojisdjfdsb_';
In addition I changed the code to:
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import Select
from selenium.webdriver.chrome.options import Options
options = webdriver.ChromeOptions()
chrome_driver_path = "../chromedriver.exe"
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument('--disable-blink-features=AutomationControlled')
driver = webdriver.Chrome(executable_path=chrome_driver_path, options=options)
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
driver.get('http://www1.nseindia.com/products/content/equities/equities/eq_security.htm')
driver.execute_script("document.body.style.zoom='zoom 25%'")
time.sleep(5)
price_volume = driver.find_element_by_xpath('//*[#id="dataType"]/option[2]').click()
time.sleep(3)
date_range = driver.find_element_by_xpath('//*[#id="dateRange"]/option[8]').click()
time.sleep(5)
series = driver.find_element_by_name('series')
time.sleep(3)
drop = Select(series)
drop.select_by_value("EQ")
time.sleep(4)
driver.find_element_by_name("symbol").send_keys("ACC")
actions = ActionChains(driver)
ez_download = driver.find_element_by_xpath('/html/body/div[2]/div[3]/div[2]/div[1]/div[3]/div/div[1]/form/div[2]/div[3]/p/img')
actions.move_to_element(ez_download)
actions.click(ez_download)
actions.perform()
#' essential because the button has to be loaded
time.sleep(5)
driver.find_element_by_class_name('download-data-link').click()
The code finally worked and the OP is happy.
I have edited the chromedriver.exe using hex editor and replaced cdc_ with dog_ and saved it. Then executed the below code using chrome driver.
import selenium
from selenium import webdriver
from selenium.webdriver.support.select import Select
import time
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_argument("--disable-blink-features")
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options)
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
driver.execute_cdp_cmd('Network.setUserAgentOverride', {"userAgent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'})
print(driver.execute_script("return navigator.userAgent;"))
# Open the website
driver.get('https://www1.nseindia.com/products/content/equities/equities/eq_security.htm')
symbol_box = driver.find_element_by_id('symbol')
symbol_box.send_keys('20MICRONS')
driver.implicitly_wait(10)
#rd_period=driver.find_element_by_id('rdPeriod')
#rd_period.click()
list_daterange=driver.find_element_by_id('dateRange')
list_daterange=Select(list_daterange)
list_daterange.select_by_value('24month')
driver.implicitly_wait(10)
btn_getdata=driver.find_element_by_xpath('//*[#id="get"]')
btn_getdata.click()
driver.implicitly_wait(100)
print("Clicked button")
lnk_downloadData=driver.find_element_by_xpath('/html/body/div[2]/div[3]/div[2]/div[1]/div[3]/div/div[3]/div[1]/span[2]/a')
lnk_downloadData.click()
This code is working fine as of now. But the problem is that - this is not a permanent solution. NSE keeps on updating the logic to detect BOT execution in a better way. Like NSE, we will also have update our code. Please let me know if this code is not working. Will figure out some other solution.

PHP, Codeception, Firefox and new tab - how to?

I have a test for PHP project which opens a new tab by double-click. I test it in Firefox.
I am new to Codeception, but I've read and tried everything I've found with no luck.
I have a table which rows are spans. I want to double-click it and to check if correct page is open.
I try:
$i->scrollTo(['xpath' => '//span[text()="test"]']);
$i->doubleClick(['xpath' => '//span[text()="test"]']);
$i->waitForText("test text", 15);
$i->seeCurrentUrlMatches('~^/register/materials/view/\d+$~');
The issue is that doubleClick opens a requested page in new tab like this:
jumpTo: function(row) {
const link = document.createElement('a');
link.href = window.location.pathname + '/view/' + row.id;
link.setAttribute('target', '_blank');
document.body.appendChild(link);
link.click();
},
If I try to run this test as is - it starts, double-clicks span, then new tab opens, focus switches to it, I see correct page and test text on it, but test fails because it does not see requested text because it seems that though I see that tab changed the WebDriver remains on first tab.
I tried switchToNextTab() - it does not work. Sometimes switchToNextTab() 3 times in a row works, sometimes not.
I tried reloadPage() - it reloads first tab, not the one recently opened.
I tried
$I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {
$handles=$webdriver->window_handles();
$last_window = end($handles);
$webdriver->focusWindow($last_window);
});
and it seems that there is one currently active window in terms of this method ($handles is an array of 1 element).
I tried closeTab() - it closes entire Firefox instance.
How can I programmatically change active tab?

Way to implement resetApp for React Native with wdio-cli/? - webdriverio

Hellow there! I am using the wdio/cli so I created the wdio.conf.js with this command, then I start doing the test. But the issues is when have more than one test in a single or multiple test files.
In the test file I have something like this:
beforeEach(async function() {
$('~home').waitForDisplayed(81000, false);
});
Where home tag is a tag in the first view when the app runs in first screen. And appear this error:
element ("~home") still not displayed after 10000ms
So need to do kind of driver.resetApp()/ But dont know how to do it, what import do I need to do etc.
Did you try resetApp? You can't user driver as "main object" - Everything is under browser variable. Try this
//async
await browser.resetApp();
//sync
browser.resetApp();
Check Appium doc + wdio documentation.

How to close file upload dialogue after click on upload button in protractor

I want to upload an image file in protractor. the problem is i can not get "input[type = "file"]" element without clicking on upload button.
when I click upload button, file upload dialogue popup opens.
i have tried
browser.actions().sendKeys(protractor.Key.ESCAPE).perform(); but it does not work.
This is what I am doing:
var image = '../images/image1.png';
var absPathImg = path.resolve(__dirname, image);
element(by.id('uploadImage')).click();
browser.actions().sendKeys(protractor.Key.ESCAPE).perform();
element(by.css('input[type=file]')).sendKeys(absPathImg);
element(by.id('upload')).click();
How can i close that file upload dialogue to upload an image?
Try it like this. I used this for Protractor, but I think it's similar for Selenium.
I also have a problem for Windows File dialog not closing.
This is how I solved that:
element(by.css('elementForOpenDialog')).sendKeys(absPathImg);
Send Keys to the element which will open file dialog, not click on element to open file dialog. Just send to that element absolute path and it will upload without opening dialog.
It's worked for me. Good Luck!
This is an old thread but I'll answer in case anyone else runs to this problem.
I had to solve this same problem today. I was able to work around opening the upload dialog, because I am quite sure it cannot be closed without some external libraries and that would not work in headless mode.
You need to inspect the javascript linked to the upload button's click event and execute some script before sending keys to the file input.
This is individual to each case, but in my case i had to do this (Python):
script = (
"var url = '/Contacting/UploadCsv'; "
"$('#buttonFileUpload').data('url', url);"
)
driver.execute_script(script)
driver.find_element_by_id('buttonFileUpload').send_keys(csv_path)
I picked that script from the JS function linked to the button.
I landed here because I was searching on HOW TO CLOSE AN IMAGE WHEN CLICKED
In case that helps someone.
So what I did.
var Img = Driver.FindElement(XPath.News.YourImg);
Img.Click();
try
{
Img.Click();
Assert.IsFalse(feedImg.Displayed);
}catch(Exception ex)
{
}
This way you can check if the image is closed by trying to click on it again.
Instead of clicking on to ESCAPE, why not simulate the ENTER key press to simulate a person entering the path and pressing the ENTER key to upload the image.
I am doing this in my code and this works perfectly fine.
var path = require('path')
this.fileUploadOne = element(by.css('locator_to_element'));
var fileUpload = 'path_of_file_to_upload'
absolutePath = path.resolve(__dirname,fileUpload);
console.log(absolutePath);
this.fileUploadOne.sendKeys(absolutePath);
browser.actions().sendKeys(protractor.Key.ENTER).perform();
//just for debugging purposes.
browser.sleep(20000);

cucumber file download confirm

I have a cucumber step where the file gets downloaded, but i am unable to click the save button in the dialog box that a browser provides, with cucumber step.
I have found some pages which solves the similar kind of problems, but it didn't solve mine
How to test a confirm dialog with Cucumber?
I have included this cucumber step for file download
When /^I confirm a js popup on the next step$/ do
page.evaluate_script("window.alert = function(msg) { return true; }")
page.evaluate_script("window.confirm = function(msg) { return true; }")
end
But didn't work.
Thanks
Did you try the page.driver syntax?
i.e., from: How to test a confirm dialog with Cuccumber?:
When /^I confirm popup$/ do
page.driver.browser.switch_to.alert.accept
end
When /^I dismiss popup$/ do
page.driver.browser.switch_to.alert.dismiss
end
ian.
I know this is old, but since this was one of the first SO posts I came across when searching for solutions, I figured I'd post a solution.
We can use good ol Ruby, along with open-uri (so include open-uri in your Gemfile if you aren't already using it):
Then /^I receive a PDF$/ do
link_url = find_link("Report")[:href]
file = open(link_url)
file.content_type.should == 'application/pdf'
end

Resources