2

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;">

enter image description here enter image description here

<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:

enter image description here enter image description here

<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.

enter image description here

When I change my print statement from print(hour.text) to print(hour) it shows this:

enter image description here

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

2 Answers 2

1

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'
Sign up to request clarification or add additional context in comments.

Comments

0

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.

3 Comments

I updated my question with more code. So I click into the input box with element id StartTime and the clock appears. If I got rid of the popover.clockpicker-popover.top.clockpicker-align-left selector my code works for the first clock but when I move to the second clock it doesn't work.
I'm guessing this is because the second clock has appeared but I haven't actually selected it and it is still reading hours/mins from the first clock which are now hidden because it goes away when this clock appears.
Ah, I thought both clocks remained visible. In that case, I'd say get the values from the first clock, click on it, get the vals from the second...But I'm sure you've already figured that out. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.