Selenium's WebDriver.execute_script() returns 'None' - selenium

My program is having trouble getting an existing class from a webpage using Selenium. It seems that my WebDriver.execute_script function is not working.
import urllib
from selenium import webdriver
#Path to the chromedriver is definitely working fine.
path_to_chromedriver = 'C:\Users\Ben\Desktop\Coding\FreeFoodFinder\chromedriver.exe'
browser = webdriver.Chrome(executable_path = path_to_chromedriver)
url = 'http://www.maidservicetexas.com/'
browser.implicitly_wait(30)
browser.get(url)
content = browser.execute_script("document.getElementsByClassName('content')");
#Just printing the first character of the returned content's toString for now. Don't want the whole thing yet.
#Only ever prints 'N', the first letter of 'None'...so obviously it isn't finding the jsgenerated content even after waiting.
print content
My program returns 'None,' which tells me that the javascript function is not returning a value/being executed. Chrome's web dev tools tell me that 'content' is certainly a valid class name. The webpage isn't even dynamically generated (my eventual goal is to scrape dynamic content, which is why I make my WebDriver wait for 30 seconds before running the script.)

Return the value:
content = browser.execute_script("return document.getElementsByClassName('content');");

Related

selenium get abs url from href attribute

when im downloading a page with selenium and process it with java jsoup. I get the hrefs in the source code like this:
Technical Trading
Is there a way to get the absolute url from this or to force selenium to transform it to an absolute url? Updating the links after getting the page doesn't sound like a clean solution.
If you get the href just with selenium, this works as expected:
yourElement.get_attribute('href')
This is a quick sample:
driver = webdriver.Chrome() # note this is my webdriver
driver.implicitly_wait(10)
url = "https://www.duckduckgo.co.uk"
driver.get(url)
aList = driver.find_elements(By.TAG_NAME, 'a')
for a in aList:
print(a.get_attribute('href'))
Output contains:
https://duckduckgo.com/spread
https://duckduckgo.com/spread
https://duckduckgo.com/app
https://duckduckgo.com/app
https://duckduckgo.com/newsletter
https://duckduckgo.com/newsletter
This is how the DOM looks: (it's relative - but gets the full path)

Send a numpad key (with Num Lock off)

I want to test how my app reacts to numpad keys. I found in https://www.w3.org/TR/webdriver/ specs that for example for Numpad Home (with location = DOM_KEY_LOCATION_NUMPAD = 3) a symbol \uE057 should be used. However, it doesn't work for me: I get Home with default location (0), moreover, event.code is empty. It gives me a different result when I physically press NUMPAD7 button with Num Lock off: it that case, I get correct location 3 and event.code is Numpad7.
var options = FirefoxOptions();
options.setLogLevel(FirefoxDriverLogLevel.TRACE);
var driver = FirefoxDriver(options);
driver.navigate().to("https://keycode.info/");
driver.findElementByTagName("body").sendKeys("\uE057");
So how can I send such a key? I'm now thinking of manual recording of generated events when I physically press a key, and then sending these events via Selenium's execution of JS script. However, I haven't tried it yet; maybe there is a better way to do it in Selenium; maybe there is another framework that allows it better.
By the way, I've filed a similar ticket in geckodriver because it looks like a bug of webdriver to me...
\ue01d is the unicode for NUmberpad3
python code:
from selenium import webdriver
from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome()
driver.get("https://keycode.info/")
driver.find_element_by_tag_name("body").send_keys("\ue01d")
input()
you can use https://www.javadoc.io/doc/org.seleniumhq.selenium/selenium-api/latest/org/openqa/selenium/Keys.html to send keys instead of sending unicode directly
In firefox this is will work if you use action chain:
ActionChains.send_keys("\ue01d").perform()

Protractor get console variable value

In Firefox browser developer tool console, I type var a = libraryform.firstname
It returns the firstname value entered by user for that form.
I am new to protractor and selenium. How can I call library.firstname in protractor to get the value of fistname?
Use Javascript Executor to execute the javascript which you able to get them working in developer console against your application.
For e.g.,
this returns web-element which retrieved through javascript executed in browser.
var element = browser.executeScript("document.getElementById('identifier1')");
Refer this page for more examples
If this single line returns required value in browser console, then the protractor code should be some thing like this,
var name = browser.executeScript('return libraryform.firstname')
If you need too many lines of js, you can specify with semicolon separated,
var name = browser.executeScript("var element=$('.dropdown-toggle').eq(0); return element.text();")

Threading and Selenium

I'm trying to make multiple tabs in Selenium and open a page on each tab simultaneously. Here is the code.
CHROME_DRIVER_PATH = "C:/chromedriver.exe"
from selenium import webdriver
import threading
driver = webdriver.Chrome(CHROME_DRIVER_PATH)
links = ["https://www.google.com/",
"https://stackoverflow.com/",
"https://www.reddit.com/",
"https://edition.cnn.com/"]
def open_page(url, tab_index):
driver.switch_to_window(handles[tab_index])
driver.get(url)
return
# open a blank tab for every link in the list
for link in range(len(links)-1 ): # 1 less because first tab is already opened
driver.execute_script("window.open();")
handles = driver.window_handles # get handles
all_threads = []
for i in range(0, len(links)):
current_thread = threading.Thread(target=open_page, args=(links[i], i,))
all_threads.append(current_thread)
current_thread.start()
for thr in all_threads:
thr.join()
Execution goes without errors, and from what I understand this should logically work correctly. But, the effect of the program is not as I imagined. It only opens one page at a time, sometimes it doesn't even switch the tab... Is there a problem that I'm not aware of in my code or threading doesn't work with Selenium?
There is no need in switching to new window to get URL, you can try below to open each URL in new tab one by one:
links = ["https://www.google.com/",
"https://stackoverflow.com/",
"https://www.reddit.com/",
"https://edition.cnn.com/"]
# Open all URLs in new tabs
for link in links:
driver.execute_script("window.open('{}');".format(link))
# Closing main (empty) tab
driver.close()
Now you can handle (if you want) all the windows from driver.window_handles as usual

Explicit in selenium

I am using Selenium to get div value, but the fallowing code is not waiting for the page, just for URL. I used time.sleep, which is very primitive and totally not flexible. I want to change it on the explicit, but I am not too experienced in Python and I have a problem with that.
The website name has been changed just in case :
def repeat():
import wx
while True:
botloc = driver.find_element_by_id('botloc').text
print botloc
botX,botY = map(int,botloc.split(','))
print botX
print botY
wx.Yield()
def checker():
if driver.current_url == 'logged.example.com':
time.sleep(5)
repeat()
else:
checker()
checker()
How can I replace time.sleep with something flexible to wait the shortest time as possible after the page will be loaded? How to use explicit correctly with my code?
I know that's possible with using an element from the website, but I can't write anything sensible, I just need an example.
Is possibility to use element_by_id('botloc') for wait till it will be visible then start repeat() ?
How can i replace time.sleep with something flexible to wait shortest
time as possible after the page will be loaded?
I suppose you use get(url) to load the page. Generally you don't have to do anything, WebDriver automatically waits until page is being loaded. So you can remove time.sleep(). However there are some issues reported when loading the page using get with firefox driver, because of that you will have to wait for some target element which is supposed to be in the loaded page as mentioned below.
How to use explicit correctly with my code?
Have you checked Selenium webdriver documentation ? you can wait for botloc element explicitly as below
//assuming you have a valid webdriver reference
//Ex: DEFAULT_WAIT = 10 means
//waits up to 10 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 10 seconds.
element = WebDriverWait(webdriver, DEFAULT_WAIT).until(EC.presence_of_element_located((By.ID, "botloc")))
Refer this page for more information