How to "send keys" to a canvas element for longer duration?
Unfortunately I cannot see a reproducible behaviour for jumps in that game. When i press UP o SPACE, I randomly see short or long jumps, so I cannot be really sure if my approach will work for you.
However, I think that, with a small effort, you could create a suitable event that will fit you needs.Basically, since Selenium can execute arbitrary javascript, my approach here is to send a keydown event to the canvas element (tested with Firefox 77).
A screenshot is made for each iteration to ensure the dino actually jumps.
Have fun.
from selenium.webdriver.firefox.options import Options as FirefoxOptionsfrom selenium import webdriverfrom selenium.webdriver.common.keys import Keysimport timeoptions = FirefoxOptions()options.add_argument("--headless")driver = webdriver.Firefox(options=options)driver.get('https://chromedino.com/')canvas = driver.find_element_by_css_selector('.runner-canvas')main_body = driver.find_element_by_xpath("//html")try: canvas.click()except: main_body.send_keys(Keys.SPACE)while True: driver.execute_script(''' var keydownEvt = new KeyboardEvent('keydown', { altKey:false, altKey: false, bubbles: true, cancelBubble: false, cancelable: true, charCode: 0, code: "Space", composed: true, ctrlKey: false, currentTarget: null, defaultPrevented: true, detail: 0, eventPhase: 0, isComposing: false, isTrusted: true, key: " ", keyCode: 32, location: 0, metaKey: false, repeat: false, returnValue: false, shiftKey: false, type: "keydown", which: 32, }); arguments[0].dispatchEvent(keydownEvt); ''', canvas) driver.get_screenshot_as_file('proof_%s.png' % int(time.time())) time.sleep(0.2)driver.quit()
You were so close. However a few words:
- The T-RexDinosaur within T-Rex Chrome Dino Game only animates within the canvas
- The control, i.e. pressing the space bar doesn't needs to be sent within the canvas but only can be initiated from the keyboard.
- In your code block for short jumps you don't need to send
Keys.SPACE
to any element. - In your code block for long jumps as well you don't need to send
Keys.SPACE
to any element and the variablekeyboard
wasn't defined as well.
Solution
As a solution once you open the url you need to induce WebDriverWait for the visibility_of_element_located()
of the canvas element and you can use either of the following Locator Strategy based solutions.
Short Jumps
For short jumps you can use:
driver.get("https://chromedino.com/")WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "canvas.runner-canvas")))while True: #short jump ActionChains(driver).key_down(Keys.SPACE).key_up(Keys.SPACE).perform()
I was consistently able to score 69-72
Snapshot:
Long Jumps with 0.2 seconds pause
For long jumps with pause(0.2)
you can use:
driver.get("https://chromedino.com/")WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "canvas.runner-canvas")))while True: #short jump # ActionChains(driver).key_down(Keys.SPACE).key_up(Keys.SPACE).perform() #long jump ActionChains(driver).key_down(Keys.SPACE).pause(0.2).key_up(Keys.SPACE).perform()
I was consistently able to score 65
Snapshot:
Long Jumps with 0.5 seconds pause
For long jumps with pause(0.5)
you can use:
driver.get("https://chromedino.com/")WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "canvas.runner-canvas")))while True: #short jump # ActionChains(driver).key_down(Keys.SPACE).key_up(Keys.SPACE).perform() #long jump ActionChains(driver).key_down(Keys.SPACE).pause(0.5).key_up(Keys.SPACE).perform()
I was consistently able to score 57-60
Snapshot:
Here is a simple solution to it -
import keyboardkeyboard.press_and_release('space', 'space', 'space')
It worked when i tried so should work. You can increase and decrease the number of time 'space'
has been written to increase the time duration or decrease it.
Hope it helped :)