How to "send keys" to a canvas element for longer duration? How to "send keys" to a canvas element for longer duration? selenium selenium

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

T-RexDino

  • 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 variable keyboard 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:

shortjump


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:

longjump_0.2


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:

longjump_0.5


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