Reputation: 1556
Using selenium and chrome driver. Python 3.5
Imagine a start time and end time box. You click into the start time box and a clock appears. The start clock is left aligned and the end clock is right aligned.
<div class="popover clockpicker-popover top clockpicker-align-left" style="display: block; top: 511px; left: 287px;">
<div class="clockpicker-dial clockpicker-hours" style="visibility: visible;"></div>
<div class="clockpicker-dial clockpicker-minutes" style="visibility: visible;"></div>
Then you click into the end time box:
<div class="popover clockpicker-popover top clockpicker-align-right" style="display: block; top: 511px; left: 287px;">
Same hours and minutes.
My issue is selecting the left and right versions of the clock. In fact, my code was working fine until I had to put in the end time and so then I decided to add code to distinguish them.
import time, sys
from selenium import webdriver
# open chrome and go to website
driver = webdriver.Chrome()
driver.get('website')
time.sleep(3)
def startHour(number):
# If I remove this line I can select hours/mins for first clock but not second clock
driver.find_element_by_css_selector('popover.clockpicker-popover.top.clockpicker-align-left')
select = driver.find_element_by_css_selector('.clockpicker-dial.clockpicker-hours')
print('Selected clockpicker hours')
for hour in select.find_elements_by_class_name('clockpicker-tick'):
print(hour.text)
if hour.text == number:
print('Hour.text: ' + hour.text)
print('Hour: ' + number)
hour.click()
break
def endHour(number):
driver.find_element_by_css_selector('popover.clockpicker-popover.top.clockpicker-align-right')
select = driver.find_element_by_css_selector('.clockpicker-dial.clockpicker-hours')
print('Selected clockpicker hours')
for hour in select.find_elements_by_class_name('clockpicker-tick'):
print(hour.text)
if hour.text == number:
print('Hour.text: ' + hour.text)
print('Hour: ' + number)
hour.click()
break
def clickMinutes(number):
select = driver.find_element_by_css_selector('.clockpicker-dial.clockpicker-minutes')
print('Selected clockpicker minutes')
for minutes in select.find_elements_by_class_name('clockpicker-tick'):
print(minutes.text)
if minutes.text == number:
print('Minutes.text: ' + minutes.text)
print('Minutes: ' + number)
minutes.click()
break
# Select start time input box, start time clock appears
driver.find_element_by_id('StartTime').click()
startHour('7')
time.sleep(4)
clickMinutes('30')
time.sleep(4)
# Select end time input box, end time clock appears
driver.find_element_by_id('EndTime').click()
time.sleep(4)
endHour('16')
time.sleep(4)
clickMinutes('00')
time.sleep(4)
driver.quit()
sys.exit()
Error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"popover.clockpicker-popover.top.clockpicker-align-left"}
When I remove that driver.find_element_by_css_selector('popover.clockpicker-popover.top.clockpicker-align-left')
it works fine for the first clock and I can open the second clock by clicking into the input box for it but I can't actually select the second clock or its elements.
Update:
It seems like it finds the hours but it prints out a bunch of empty lines which makes me think it's still on the first clock which is hidden when the second clock comes up.
When I change my print statement from print(hour.text)
to print(hour)
it shows this:
24 elements for the 24 hours.
ANSWER:
I added the periods in front of popover.clockpicker...
and also appended the next find element by css selector and it worked! Thank you everyone for your help.
def startHour(number):
select = driver.find_element_by_css_selector('.popover.clockpicker-popover.top.clockpicker-align-left').find_element_by_css_selector('.clockpicker-dial.clockpicker-hours')
print('Selected clockpicker hours')
for hour in select.find_elements_by_class_name('clockpicker-tick'):
print(hour.text)
if hour.text == number:
print('Hour.text: ' + hour.text)
print('Hour: ' + number)
hour.click()
break
def endHour(number):
select = driver.find_element_by_css_selector('.popover.clockpicker-popover.top.clockpicker-align-right').find_element_by_css_selector('.clockpicker-dial.clockpicker-hours')
print('Selected clockpicker hours')
for hour in select.find_elements_by_class_name('clockpicker-tick'):
print(hour.text)
if hour.text == number:
print('Hour.text: ' + hour.text)
print('Hour: ' + number)
hour.click()
break
Upvotes: 2
Views: 329
Reputation: 52665
I guess your issue caused by typo in your selector:
'popover.clockpicker-popover.top.clockpicker-align-left'
actually means that you want to handle
<popover class="clockpicker-popover top clockpicker-align-left">
element, so you need to add leading point as
'.popover.clockpicker-popover.top.clockpicker-align-left'
Upvotes: 1
Reputation: 13
So, it sounds like it is popping the first clock (align-left), but your error indicates that it is this element that is failing. That seems wrong...
Also, you mention that you have to actually click into the first clock before the second one appears, and I don't see where you are doing that.
Upvotes: 0