0

I'm working on Nytimes mini crossword puzzle (https://www.nytimes.com/crosswords/game/mini) .

First I need to click the "OK" button when the page loads (I did this)

then "Reveal" then "Puzzle" from the menu at the right but the buttons has not specific ids itselves as you can see below.

<div class="Toolbar-expandedMenu--2s4M4">
  <li class="Tool-button--39W4J Tool-tool--Fiz94 Tool-texty--2w4Br"><button>clear</button>
    <ul class="HelpMenu-menu--1Z_OA">
      <li class="HelpMenu-item--1xl0_" style="display:list-item" title="Won’t clear letters that are part of completed crossing words"><a>Incomplete</a></li>
      <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Word</a></li>
      <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Puzzle</a></li>
      <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Puzzle &amp; Timer</a></li>
    </ul>
  </li>
  <li class="Tool-button--39W4J Tool-tool--Fiz94 Tool-texty--2w4Br Tool-open--1Moaq"><button>reveal</button>
    <ul class="HelpMenu-menu--1Z_OA">
      <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Square</a></li>
      <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Word</a></li>
      <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Puzzle</a></li>
    </ul>
  </li>
  <li class="Tool-button--39W4J Tool-tool--Fiz94 Tool-texty--2w4Br"><button>check</button>
    <ul class="HelpMenu-menu--1Z_OA">
      <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Autocheck</a></li>
      <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Square</a></li>
      <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Word</a></li>
      <li class="HelpMenu-item--1xl0_" style="display:list-item"><a>Puzzle</a></li>
    </ul>
  </li>
</div>

Here is my python script

from selenium import webdriver
import time

driver_path = "/home/xperia/PycharmProjects/cs461-getinput/chromedriver"
browser = webdriver.Chrome(executable_path=driver_path)
browser.get("https://www.nytimes.com/crosswords/game/mini")
time.sleep(5)
browser.find_element_by_class_name("buttons-modalButton--1REsR").click()
time.sleep(5)
browser.find_element_by_class_name("Tool-button--39W4J Tool-tool--Fiz94 Tool-texty--2w4Br").click()
1
  • I found that in chrome dev tools you right click an element then copy its path as xpath then we can use the method "browser.find_element_by_xpath" easier Commented Sep 30, 2019 at 19:44

3 Answers 3

2

You can click on an element using its text, rather than ID. In your case, this may help, since the elements do not have ID.

To click the reveal button:

# wait for reveal button to exist
WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//button[contains(text(), 'reveal')]'))).click()

# click reveal button
browser.find_element_by_xpath("//button[contains(text(), 'reveal')]").click()

To click Puzzle, you can use this path:

# wait for puzzle button to exist
WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//li[button[contains(text(), 'reveal')]]/ul/li/a[text()='Puzzle']'))).click()

# click the reveal button
browser.find_element_by_xpath("//li[button[contains(text(), 'reveal')]]/ul/li/a[text()='Puzzle']").click()
Sign up to request clarification or add additional context in comments.

Comments

1

To click on puzzle under reveal menu induce WebDriverWait And element_to_be_clickable()

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver_path = "/home/xperia/PycharmProjects/cs461-getinput/chromedriver"
browser = webdriver.Chrome(executable_path=driver_path)
browser.get("https://www.nytimes.com/crosswords/game/mini")
WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//span[text()="ACCEPT AND CLOSE"]'))).click()
WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.CLASS_NAME,'buttons-modalButton--1REsR'))).click()
WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//div[@class="Toolbar-expandedMenu--2s4M4"]//li/button[text()="reveal"]'))).click()
WebDriverWait(browser,10).until(EC.element_to_be_clickable((By.XPATH,'//button[text()="reveal"]/following::ul[1]//li/a[text()="Puzzle"]'))).click()

Comments

1

I edited your script a little bit. I tested this on my end and it works up to the point of pressing the 'Puzzle' button. I recommend using xpath as well. You can get the xpath element by clicking inspect until the location of the element pops up, then right click and copy by xpath. This is what the code looks like

from selenium import webdriver
import time

driver_path = "/home/xperia/PycharmProjects/cs461-getinput/chromedriver"
browser = webdriver.Chrome(executable_path=driver_path)
time.sleep(3)
browser.find_element_by_class_name("buttons-modalButton--1REsR").click()
time.sleep(2)
browser.find_element_by_xpath('//*[@id="root"]/div/div/div[4]/div/main/div[2]/div/div/ul/div[2]/li[2]/button').click()
browser.find_element_by_xpath('//*[@id="root"]/div/div/div[4]/div/main/div[2]/div/div/ul/div[2]/li[2]/ul/li[3]/a').click()

Also important to note that if you get an error, it might be because there is another element blocking the button you want clicked.

3 Comments

This is a good solution, but the XPaths are a little lengthy, and indices such as [4] make them more brittle. You can accomplish the same result with relative XPath that does not rely on indices, and shorter in length.
Ah! Thanks for the tip, I will definitely try to incorporate this more.
Thank you very much for your answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.