I am trying to perform a test on Amazon.com categories checkboxes using selenium web driver with python code, and I tried several ways but I am not sure how to select the checkbox of the Book category for example without having its id or name. I used some plugins to get the right xpath like XPath Helper for chrome and path checker on Firefox...
Here is my code and my tries are commented.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from time import sleep
import unittest
class Test_PythonOrg(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Firefox()
def tearDown(self):
sleep(4)
self.browser.close()
self.browser = None
def test_07_ListOfTodayDeals(self):
self.browser.get("http://www.amazon.com")
deals = self.browser.find_element_by_link_text("Today's Deals")
deals.click()
books = self.browser.find_element_by_id("widgetFilters")
books.find_element_by_xpath("/x:div[1]/x:div/x:span[8]/x:div/x:label/x:span").click()
#for i in range(20):
#try:
#self.browser.find_element_by_xpath(".//*[contains(text(), 'Books')]").click()
#break
#except NoSuchElementException as e:
#print('retry')
#time.sleep(1)
#else:
#print('Test Failed')
browser.close()
#sign_in_button = self.browser.find_element(By_XPATH,'(//input[#name=''])[8]')
#sign_in_button.find_element_by_xpath("//select[#name='element_name']/option[text()='option_text']").click()
#sleep(5)
#self.assertTrue("No results found." not in self.browser.page_source)
if __name__ == "__main__":
unittest.main(verbosity=2)
HTML
<span class="a-declarative" data-action="gbfilter-checkbox" data-gbfilter-checkbox="{"attribute":"whitelist_categories","value":"283155","rangeEnd":"","rangeStart":"","filterType":"checkboxes"}">
<div class="a-checkbox checkbox checked a-spacing-micro"><label><input name="" value="" checked="" type="checkbox"><i class="a-icon a-icon-checkbox"></i><span class="a-label a-checkbox-label">
Books
</span></label></div>
</span>
I have solved my problem with a very simple line of code using the right xpath:
self.browser.find_element_by_xpath("(//input[#name=''])[8]").click()
and it perfectly worked!
I have modified your code and now it's working
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from time import sleep
import unittest
class Test_PythonOrg(unittest.TestCase):
def setUp(self):
self.browser = webdriver.Firefox()
def tearDown(self):
sleep(4)
self.browser.close()
self.browser = None
def test_07_ListOfTodayDeals(self):
self.browser.get("http://www.amazon.com")
deals = self.browser.find_element_by_link_text("Today's Deals")
deals.click()
sleep(5)
self.browser.find_element_by_xpath("//span[#class='a-label a-checkbox-label' and contains(text(),'Books')]/preceding-sibling::input[1]").click()
self.browser.close()
if __name__ == "__main__":
unittest.main(verbosity=2)
Related
import time
import self as self
from pytest import mark
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from setuptools import setup
#mark.execute
class First_Tests:
def test_first(self, setup):
driver = setup['driver']
browser = setup['browser']
driver.get("https://shuftipro.com/")
driver.maximize_window()
def header_test(self, setup):
driver = setup['driver']
# Click on solution in header
solution = driver.find_element(By.ID, "menu-item-72751")
solution.click()
if driver.current_url == "https://shuftipro.com/solutions/":
print("land on solution page.")
else:
print("land on wrong page.")
obj = First_Tests()
obj.test_first(self, setup)
obj.header_test(self, setup)
If I remove the "self" from parameter and run the program it showing me error that, test_first() takes 1 positional arguments but 3 were given
one of easier way would be to use webdriver from selenium
driver = webdriver.Chrome()
and remove
driver = setup['driver']
browser = setup['browser']
and then get rid of setup as parameter.
The final code will look something like this:
from pytest import mark
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
#mark.execute
class First_Tests:
def test_first(self):
driver.get("https://shuftipro.com/")
driver.maximize_window()
def header_test(self):
# Click on solution in header
solution = driver.find_element(By.ID, "menu-item-72751")
solution.click()
if driver.current_url == "https://shuftipro.com/solutions/":
print("land on solution page.")
else:
print("land on wrong page.")
obj = First_Tests()
obj.test_first()
obj.header_test()
I'm creating rambler autoreg mail using selenium python and encountered a problem that selenium can't find the item by xpath on the page, although it is there. It's clear from the error that selenium just can't find the item (error text at the very bottom). Been looking for a solution, but they are mostly all related to another problem, please help you, thanks in advance.
HTML
...
<footer class = "styles_popupFooter__1pUND" ...>
<div class="styles_footer__wCsAz rui-Typography-reset rui-Typography-text">
<a class="styles_link___lR7s styles_link__lCdad" ... >Registration<a>
...
<div>
...
<footer>
...
Python
# Selenium 4
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
class GenerateEmail:
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(driver, 30)
def main(self):
url = "https://mail.rambler.ru/?utm_source=head&utm_campaign=self_promo&utm_medium=header&utm_content=mail"
self.driver.get(url)
value = '//div[#class="styles_footer__wCsAz rui-Typography-reset rui-Typography-text"]//a[text()="Registration"]'
self.wait.until(EC.element_to_be_clickable((By.XPATH, value)))
button = self.driver.find_element(by=By.XPATH, value=value)
button.click()
def start():
try:
s = Service(executable_path='driver/geckodriver.exe')
driver = webdriver.Firefox(service=s)
g_email = GenerateEmail(driver)
g_email.main()
except Exception as e:
print(e)
finally:
driver.close()
if __name__ == '__main__':
start()
Error
Message:
Stacktrace:
WebDriverError#chrome://remote/content/shared/webdriver/Errors.jsm:186:5
NoSuchElementError#chrome://remote/content/shared/webdriver/Errors.jsm:398:5
element.find/</<#chrome://remote/content/marionette/element.js:300:16
The element Registration you are after is inside an iframe you need switch it first in order to access the element. Use Webdriverwait() and frame_to_be_available_and_switch_to_it()
def main(self):
url = "https://mail.rambler.ru/?utm_source=head&utm_campaign=self_promo&utm_medium=header&utm_content=mail"
self.driver.get(url)
self.wait.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//div[#data-id-frame='embed']//iframe")))
value = '//div[#class="styles_footer__wCsAz rui-Typography-reset rui-Typography-text"]//a[text()="Registration"]'
self.wait.until(EC.element_to_be_clickable((By.XPATH, value)))
button = self.driver.find_element(by=By.XPATH, value=value)
button.click()
I'm pretty new to Python and coding in general, but I've been working on a datascraping project and I have been stuck for a couple days. Right now I am trying to make my code navigate through different pages in TripAdvisor. The code allows me to move to the second page fine, but it has a problem moving to the third page and forward. I am trying to have it in a loop and I think that's where the main problem stems from. If anyone could help out, that would be greatly appreciated.
My code so far:
import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import ElementNotInteractableException
from bs4 import BeautifulSoup
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import StaleElementReferenceException
from selenium.common.exceptions import ElementClickInterceptedException
import re
import pandas as pd
import time
URL = "https://www.tripadvisor.com/Hotels-g60763-New_York_City_New_York-Hotels.html"
class PythonOrgSearch(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
def test_search_in_python_org(self):
driver = self.driver
driver.get(URL)
self.assertIn("Hotel", driver.title)
driver.execute_script("window.scrollTo(0, 3400)")
time.sleep(2)
see_all = driver.find_element(By.XPATH, '//*[#id="component_6"]/div/button')
time.sleep(10)
see_all.click()
driver.execute_script("window.scrollTo(0, 11300)")
time.sleep(10)
#wait = WebDriverWait(driver,20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "a.nav.next.ui_button.primary")))
next = driver.find_element(By.CSS_SELECTOR, "a.nav.next.ui_button.primary")
here = next.is_displayed()
while here == True:
time.sleep(8)
next.click()
time.sleep(8)
driver.execute_script("window.scrollTo(0, 11300)")
time.sleep(10)
if here != True:
time.sleep(8)
break
if __name__ == "__main__":
unittest.main()
You're getting this exception because after you click on Next button new page is loaded (new DOM) and WebElement defined on previous page is no more valid (it is stale). You need to re-define next on each loop iteration
I have a select box on my page. I click on it to expand it and all values are displayed. Now i take screenshot, but in screenshot, select box is not expanded. Please check.
Code:
import unittest
from selenium import webdriver
import datetime
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.common.exceptions import NoSuchElementException
from unittest import TestCase
import re
import time
import autoit
url="https://www.facebook.com"
class SprintTests(unittest.TestCase):
def setUp(self):
self.verificationErrors = []
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.driver.maximize_window()
self.driver.get(url)
def test_offer_1(self):
a=self.driver.find_element_by_id("day")
a.click()
time.sleep(5)
self.driver.save_screenshot("res.jpg")
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main(verbosity=2)
Image generated by my code:
Expected Image:
With the given situation, it is expected to behave in this way.
When you perform save_screenshot on driver object, the driver object is now busy getting the screenshot for you instead of keeping the select menu open.
One possible solution is that you launch the save_screenshot method in different thread.
I have a functional test 'y1.py' which I have exported from the selenium IDE. It looks like:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re
class Y1(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "https://www.yahoo.com/"
self.verificationErrors = []
self.accept_next_alert = True
def test_y1(self):
driver = self.driver
driver.get(self.base_url)
driver.find_element_by_link_text("Weather").click()
driver.save_screenshot('out11.png')
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()
I am trying to call this directly from within a python/django function. while investigating this I came across: AttributeError 'module' object has no attribute 'runserver' in django, where Udi states:
Are you trying to run unitest and selenium from a view? You should
consider launching a second process for that.
How can I do this?
You can start django server as new process with subprocess module.