def send_keys(loc, text): """Sends the supplied keys to an element. Handles the file upload fields on background. If it detects the element is and input of type file, it uses the LocalFileDetector so the file gets transferred properly. Otherwise it takes care of having UselessFileDetector. Args: loc: A locator, expects either a string, WebElement, tuple. text: The text to inject into the element. """ if text is not None: file_intercept = False # If the element is input type file, we will need to use the file detector if tag(loc) == 'input': type_attr = get_attribute(loc, 'type') if type_attr and type_attr.strip() == 'file': file_intercept = True try: if file_intercept: # If we detected a file upload field, let's use the file detector. browser().file_detector = LocalFileDetector() move_to_element(loc).send_keys(text) finally: # Always the UselessFileDetector for all other kinds of fields, so do not leave # the LocalFileDetector there. if file_intercept: browser().file_detector = UselessFileDetector() wait_for_ajax()
def client() -> Remote: options: ChromeOptions = ChromeOptions() options.add_argument("--start-maximized") options.add_argument(f"--proxy-server={settings.proxy()}") capabilities: Dict[str, Any] = options.to_capabilities() capabilities["idleTimeout"] = 10800 return Remote( command_executor=settings.grid_url(), desired_capabilities=capabilities, file_detector=UselessFileDetector(), )
def setUpClass(cls): if 'DRONE_BUILD_NUMBER' in os.environ: # Listen on Docker interface in Drone cls.host = socket.gethostbyname(socket.gethostname()) if DO_SELENIUM: cls.caps['name'] = 'Weblate CI build' if 'screenResolution' not in cls.caps: cls.caps['screenResolution'] = '1280x1024' # Fill in Travis details in caps if 'TRAVIS_JOB_NUMBER' in os.environ: cls.caps['tunnel-identifier'] = os.environ['TRAVIS_JOB_NUMBER'] cls.caps['build'] = os.environ['TRAVIS_BUILD_NUMBER'] cls.caps['tags'] = [ 'python-{0}'.format(os.environ['TRAVIS_PYTHON_VERSION']), 'django-{0}'.format(django.get_version()), 'CI' ] elif 'DRONE_BUILD_NUMBER' in os.environ: cls.caps['tunnel-identifier'] = os.environ['DRONE_BUILD_NUMBER'] cls.caps['build'] = os.environ['DRONE_BUILD_NUMBER'] cls.caps['tags'] = ['CI'] # Use Sauce connect cls.username = os.environ['SAUCE_USERNAME'] cls.key = os.environ['SAUCE_ACCESS_KEY'] # We do not want to use file detector as it magically uploads # anything what matches local filename cls.driver = webdriver.Remote( desired_capabilities=cls.caps, command_executor="http://{0}:{1}@{2}/wd/hub".format( cls.username, cls.key, 'ondemand.saucelabs.com', ), file_detector=UselessFileDetector(), ) cls.driver.implicitly_wait(5) cls.actions = webdriver.ActionChains(cls.driver) jobid = cls.driver.session_id print( 'Sauce Labs job: https://saucelabs.com/jobs/{0}'.format(jobid) ) cls.image_path = os.path.join(settings.BASE_DIR, 'test-images') if not os.path.exists(cls.image_path): os.makedirs(cls.image_path) super(SeleniumTests, cls).setUpClass()
def create(self): try: browser = tries(2, WebDriverException, self.webdriver_class, **self.processed_browser_args()) except URLError as e: if e.reason.errno == 111: # Known issue raise RuntimeError( "Could not connect to Selenium server. Is it up and running?" ) else: # Unknown issue raise browser.file_detector = UselessFileDetector() browser.maximize_window() return browser
def send_keys(self, text: str, locator: LocatorAlias, *args, **kwargs) -> None: """Sends keys to the element. Detects the file inputs automatically. Args: text: Text to be inserted to the element. *args: See :py:meth:`elements` **kwargs: See :py:meth:`elements` """ text = str(text) or "" file_intercept = False # If the element is input type file, we will need to use the file detector if self.tag(locator, *args, **kwargs) == "input": type_attr = self.get_attribute("type", locator, *args, **kwargs) if type_attr and type_attr.strip() == "file": file_intercept = True try: if file_intercept: # If we detected a file upload field, let's use the file detector. self.selenium.file_detector = LocalFileDetector() el = self.move_to_element(locator, *args, **kwargs) self.plugin.before_keyboard_input(el, text) self.logger.debug("send_keys %r to %r", text, locator) result = el.send_keys(text) if Keys.ENTER not in text: try: self.plugin.after_keyboard_input(el, text) except StaleElementReferenceException: pass else: self.logger.info( "skipped the after_keyboard_input call due to %r containing ENTER.", text, ) return result finally: # Always the UselessFileDetector for all other kinds of fields, so do not leave # the LocalFileDetector there. if file_intercept: self.selenium.file_detector = UselessFileDetector()
def upload_image(browser_object: str, filepath: str): try: print('finding upload image button') browser_object.file_detector = UselessFileDetector() options_button = browser_object.find_element_by_xpath( "//div[@class='q02Nz _0TPg']//*[@aria-label='New Post']") ActionChains(browser_object).move_to_element( options_button).click().perform() time.sleep(return_randomtime()) print('selecting file on local file system') pyautogui.write(filepath, interval=0.25) pyautogui.press('return') pyautogui.press('enter') btn = pyautogui.locateOnScreen('screenshots/open.png') if btn: top = (btn[0] + (btn[2] / 2)) bottom = (btn[1] + (btn[3] / 2)) pyautogui.click(x=top, y=bottom) print('file pushed to browser. now to resize and add the tags.') time.sleep(30) return browser_object except Exception as ex: browser_object.quit() print('error in upload_image():', ex)
def start(webdriver_name=None, base_url=None, **kwargs): """Starts a new web browser If a previous browser was open, it will be closed before starting the new browser Args: webdriver_name: The name of the selenium Webdriver to use. Default: 'Firefox' base_url: Optional, will use ``utils.conf.env['base_url']`` by default **kwargs: Any additional keyword arguments will be passed to the webdriver constructor """ # Try to clean up an existing browser session if starting a new one if thread_locals.browser is not None: quit() browser_conf = conf.env.get('browser', {}) if webdriver_name is None: # If unset, look to the config for the webdriver type # defaults to Firefox webdriver_name = browser_conf.get('webdriver', 'Firefox') webdriver_class = getattr(webdriver, webdriver_name) if base_url is None: base_url = store.base_url # Pull in browser kwargs from browser yaml browser_kwargs = browser_conf.get('webdriver_options', {}) # Handle firefox profile for Firefox or Remote webdriver if webdriver_name == 'Firefox': browser_kwargs['firefox_profile'] = _load_firefox_profile() elif (webdriver_name == 'Remote' and browser_kwargs['desired_capabilities']['browserName'] == 'firefox'): browser_kwargs['browser_profile'] = _load_firefox_profile() # Update it with passed-in options/overrides browser_kwargs.update(kwargs) if webdriver_name != 'Remote' and 'desired_capabilities' in browser_kwargs: # desired_capabilities is only for Remote driver, but can sneak in del (browser_kwargs['desired_capabilities']) if webdriver_name == 'Remote' and 'webdriver_wharf' in browser_conf and not thread_locals.wharf: # Configured to use wharf, but it isn't configured yet; check out a webdriver container wharf = Wharf(browser_conf['webdriver_wharf']) # TODO: Error handling! :D wharf.checkout() atexit.register(wharf.checkin) thread_locals.wharf = wharf if browser_kwargs['desired_capabilities']['browserName'] == 'chrome': # chrome uses containers to sandbox the browser, and we use containers to # run chrome in wharf, so disable the sandbox if running chrome in wharf co = browser_kwargs['desired_capabilities'].get( 'chromeOptions', {}) arg = '--no-sandbox' if 'args' not in co: co['args'] = [arg] elif arg not in co['args']: co['args'].append(arg) browser_kwargs['desired_capabilities']['chromeOptions'] = co if thread_locals.wharf: # Wharf is configured, make sure to use its command_executor wharf_config = thread_locals.wharf.config browser_kwargs['command_executor'] = wharf_config['webdriver_url'] view_msg = 'tests can be viewed via vnc on display {}'.format( wharf_config['vnc_display']) logger.info('webdriver command executor set to %s', wharf_config['webdriver_url']) logger.info(view_msg) write_line(view_msg, cyan=True) try: browser = tries(3, WebDriverException, webdriver_class, **browser_kwargs) browser.file_detector = UselessFileDetector() browser.maximize_window() browser.get(base_url) thread_locals.browser = browser except urllib2.URLError as ex: # connection to selenium was refused for unknown reasons if thread_locals.wharf: # If we're running wharf, try again with a new container logger.error( 'URLError connecting to selenium; recycling container. URLError:' ) # Plus, since this is a really weird thing that we need to figure out, # throw a message out to the terminal for visibility write_line( 'URLError caused container recycle, see log for details', red=True) logger.exception(ex) thread_locals.wharf.checkin() thread_locals.wharf = None start(webdriver_name, base_url, **kwargs) else: # If we aren't running wharf, raise it raise return thread_locals.browser
def disableFileUploadForSendKeys(self): self.driver.file_detector = UselessFileDetector()
def driver(self, platform=None, connection_timeout=None, page_load_timeout=None, retry=None): """return desired driver if platform is a list of platforms then you can use the drivers function platform = {desired_capabilities, app, size, command_executor, browser_profile, proxy, keep_alive, file_detector, options} :param platform: dictionary with: command_executor: it's the remote driver url: default='http://127.0.0.1:4444/wd/hub' desired_capabilities: {"browserName": "chrome", "version": "67.0", "platform": "WINDOWS"} browser_profile=None, proxy=None, keep_alive=False, file_detector=None, options=None :param connection_timeout: :param page_load_timeout: :param retry: :rtype: WebDriver or MobileDriver """ if platform is None: platform = self.platform if platform['api'] == API.WEB: # set retry if retry is None: retry = settings.webdriver_retries # set page load timeout if connection_timeout is None: connection_timeout = settings.webdriver_connection_timeout # get remote connection for r in range(retry+1): try: # from selenium.webdriver.common.desired_capabilities import DesiredCapabilities # driver: WebDriver = platform['api']( # command_executor=platform['command_executor'], # desired_capabilities=platform['desired_capabilities'], # browser_profile=platform['browser_profile'], # proxy=platform['proxy'], # keep_alive=platform['keep_alive'], # file_detector=platform['file_detector'], # options=platform['options']) # get driver from thread with timeout for connection driver: WebDriver = threaders.thread( platform['api'], command_executor=platform['command_executor'], desired_capabilities=platform['desired_capabilities'], browser_profile=platform['browser_profile'], proxy=platform['proxy'], keep_alive=platform['keep_alive'], file_detector=platform['file_detector'], options=platform['options'] ).get_and_join(timeout=connection_timeout) break except Exception as e: if r == retry: raise DriverConnectionException("webdriver connection could not be established") from e # set local file detector driver.file_detector = UselessFileDetector() # set page load timeout if page_load_timeout is None: page_load_timeout = settings.webdriver_page_load_timeout # get app url for r in range(retry + 1): try: # page load from thread with timeout threaders.thread(driver.execute, Command.GET, {'url': platform["desired_capabilities"]["app"]}).get_and_join(timeout=page_load_timeout) # driver.get(platform["desired_capabilities"]["app"]) break except Exception as e: if r == retry: driver.quit() raise Exception("url could not be loaded") from e # try: # resolution = platform["desired_capabilities"]['screenResolution'].split("x") # # driver.execute_script("window.moveTo(arguments[0], arguments[1]);", 0, 0) # try: # driver.set_window_position(0, 0) # except Exception as e: # print(e) # try: # driver.set_window_size(int(resolution[0]), int(resolution[1])) # except: # driver.maximize_window() # except Exception as e: # # driver.quit() # # raise RequiredCapabilitiesException("setting screen size failed: please make sure your screenResolution capability is correct - example: 800x600x24 ") from e # print("cannot set the screen size") if platform['api'] == API.MOBILE: # set retry if retry is None: retry = settings.mobiledriver_retries # set page load timeout if connection_timeout is None: connection_timeout = settings.mobiledriver_connection_timeout for r in range(retry + 1): try: driver: MobileDriver = threaders.thread( platform['api'], command_executor=platform['command_executor'], desired_capabilities=platform['desired_capabilities'], browser_profile=platform['browser_profile'], proxy=platform['proxy'], keep_alive=platform['keep_alive'] ).get_and_join(timeout=connection_timeout) break except Exception as e: if r == retry: try: driver.quit() except: pass raise DriverConnectionException("webdriver connection could not be established") from e return driver