class Selenium::WebDriver::Remote::W3CBridge
Low level bridge to the remote server, through which the rest of the API works.
@api private
Licensed to the Software Freedom Conservancy (SFC) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The SFC licenses this file to you under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Constants
- COMMANDS
- QUIT_ERRORS
Attributes
Public Class Methods
Defines a wrapper method for a command, which ultimately calls execute.
@param name [Symbol]
name of the resulting method
@param verb [Symbol]
the appropriate http verb, such as :get, :post, or :delete
@param url [String]
a URL template, which can include some arguments, much like the definitions on the server. the :session_id parameter is implicitly handled, but the remainder will become required method arguments.
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 48 def self.command(name, verb, url) COMMANDS[name] = [verb, url.freeze] end
Initializes the bridge with the given server URL.
@param url [String] url for the remote server @param http_client [Object] an HTTP client instance that implements the same protocol as Http::Default @param desired_capabilities [Capabilities] an instance of Remote::Capabilities describing the capabilities you want
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 63 def initialize(opts = {}) if opts.fetch(:desired_capabilities, {})[:browser_name] == 'MicrosoftEdge' require_relative '../edge/legacy_support' extend Edge::LegacySupport end opts = opts.dup http_client = opts.delete(:http_client) { Http::Default.new } desired_capabilities = opts.delete(:desired_capabilities) { W3CCapabilities.firefox } url = opts.delete(:url) { "http://#{Platform.localhost}:4444/wd/hub" } desired_capabilities = W3CCapabilities.send(desired_capabilities) if desired_capabilities.is_a? Symbol desired_capabilities[:marionette] = opts.delete(:marionette) unless opts[:marionette].nil? if desired_capabilities[:marionette] && Firefox::Binary.version < 45 raise Error::WebDriverError, "Marionette is not supported in Firefox Version #{Firefox::Binary.version}" end unless opts.empty? raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}" end uri = url.kind_of?(URI) ? url : URI.parse(url) uri.path += "/" unless uri.path =~ /\/$/ http_client.server_url = uri @http = http_client @capabilities = create_session(desired_capabilities) @file_detector = nil end
Public Instance Methods
alerts
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 158 def acceptAlert execute :acceptAlert end
cookies
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 371 def addCookie(cookie) execute :addCookie, {}, :cookie => cookie end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 97 def browser @browser ||= ( name = @capabilities.browser_name name ? name.gsub(" ", "_").to_sym : 'unknown' ) end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 439 def clearElement(element) execute :elementClear, :id => element end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 305 def clearLocalStorage executeScript("localStorage.clear()") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 329 def clearSessionStorage executeScript("sessionStorage.clear()") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 400 def click execute :click, {}, :button => 0 end
actions
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 396 def clickElement(element) execute :elementClick, :id => element end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 225 def close execute :closeWindow end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 408 def contextClick execute :click, {}, :button => 2 end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 125 def create_session(desired_capabilities) resp = raw_execute :newSession, {}, :desiredCapabilities => desired_capabilities @session_id = resp['sessionId'] or raise Error::WebDriverError, 'no sessionId in returned payload' W3CCapabilities.json_create resp['value'] end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 388 def deleteAllCookies getAllCookies.each { |cookie| deleteCookie(cookie['name'])} end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 375 def deleteCookie(name) execute :deleteCookie, :name => name end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 162 def dismissAlert execute :dismissAlert end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 404 def doubleClick execute :doubleClick end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 449 def dragElement(element, right_by, down_by) execute :dragElement, {:id => element}, :x => right_by, :y => down_by end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 104 def driver_extensions [ DriverExtensions::HasInputDevices, DriverExtensions::UploadsFiles, DriverExtensions::TakesScreenshot, DriverExtensions::HasSessionId, DriverExtensions::Rotatable, DriverExtensions::HasTouchScreen, DriverExtensions::HasRemoteStatus, DriverExtensions::HasWebStorage ] end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 362 def executeAsyncScript(script, *args) result = execute :executeAsyncScript, {}, :script => script, :args => args unwrap_script_result result end
javascript execution
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 357 def executeScript(script, *args) result = execute :executeScript, {}, :script => script, :args => args unwrap_script_result result end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 571 def find_element_by(how, what, parent = nil) how, what = convert_locators(how, what) if parent id = execute :findChildElement, {:id => parent}, {:using => how, :value => what} else id = execute :findElement, {}, {:using => how, :value => what} end Element.new self, element_id_from(id) end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 583 def find_elements_by(how, what, parent = nil) how, what = convert_locators(how, what) if parent ids = execute :findChildElements, {:id => parent}, {:using => how, :value => what} else ids = execute :findElements, {}, {:using => how, :value => what} end ids.map { |id| Element.new self, element_id_from(id) } end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 260 def fullscreenWindow execute :fullscreenWindow end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 138 def get(url) execute :get, {}, :url => url end
finding elements
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 566 def getActiveElement Element.new self, element_id_from(execute(:getActiveElement)) end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 170 def getAlertText execute :getAlertText end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 384 def getAllCookies execute :getAllCookies end
TODO - write specs
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 380 def getCookie(name) execute :getCookie, :name => name end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 186 def getCurrentUrl execute :getCurrentUrl end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 241 def getCurrentWindowHandle execute :getWindowHandle end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 515 def getElementAttribute(element, name) execute :getElementAttribute, :id => element, :name => name end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 527 def getElementLocation(element) data = execute :getElementRect, :id => element Point.new data['x'], data['y'] end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 533 def getElementLocationOnceScrolledIntoView(element) sendKeysToElement(element, ['']) getElementLocation(element) end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 538 def getElementSize(element) data = execute :getElementRect, :id => element Dimension.new data['width'], data['height'] end
element properties
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 511 def getElementTagName(element) execute :getElementTagName, :id => element end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 523 def getElementText(element) execute :getElementText, :id => element end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 519 def getElementValue(element) execute :getElementProperty, :id => element, :name => 'value' end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 558 def getElementValueOfCssProperty(element, prop) execute :getElementCssValue, :id => element, :property_name => prop end
HTML 5
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 289 def getLocalStorageItem(key) executeScript("return localStorage.getItem('#{key}')") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 297 def getLocalStorageKeys executeScript("return Object.keys(localStorage)") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 309 def getLocalStorageSize executeScript("return localStorage.length") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 337 def getLocation raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting location' end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 345 def getNetworkConnection raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting network connection' end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 194 def getPageSource executeScript("var source = document.documentElement.outerHTML;" + "if (!source) { source = new XMLSerializer().serializeToString(document); }" + "return source;") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 503 def getScreenOrientation execute :getScreenOrientation end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 281 def getScreenshot execute :takeScreenshot end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 313 def getSessionStorageItem(key) executeScript("return sessionStorage.getItem('#{key}')") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 321 def getSessionStorageKeys executeScript("return Object.keys(sessionStorage)") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 333 def getSessionStorageSize executeScript("return sessionStorage.length") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 190 def getTitle execute :getTitle end
window handling
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 237 def getWindowHandles execute :getWindowHandles end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 277 def getWindowPosition(_handle = nil) raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting the Window Position' end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 264 def getWindowSize(handle = :current) unless handle == :current raise Error::UnsupportedOperationError, 'Switch to desired window before getting its size' end data = execute :getWindowSize Dimension.new data['width'], data['height'] end
navigation
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 178 def goBack execute :back end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 182 def goForward execute :forward end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 552 def isElementDisplayed(element) jwp = Selenium::WebDriver::Remote::Bridge::COMMANDS[:isElementDisplayed] self.class.command(:isElementDisplayed, jwp.first, jwp.last) execute :isElementDisplayed, :id => element end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 544 def isElementEnabled(element) execute :isElementEnabled, :id => element end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 548 def isElementSelected(element) execute :isElementSelected, :id => element end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 253 def maximizeWindow(handle = :current) unless handle == :current raise Error::UnsupportedOperationError, 'Switch to desired window before changing its size' end execute :maximizeWindow end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 412 def mouseDown execute :mouseDown end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 420 def mouseMoveTo(element, x = nil, y = nil) params = { :element => element } if x && y params.merge! :xoffset => x, :yoffset => y end execute :mouseMoveTo, {}, params end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 416 def mouseUp execute :mouseUp end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 219 def quit execute :deleteSession http.close rescue *QUIT_ERRORS end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 229 def refresh execute :refresh end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 293 def removeLocalStorageItem(key) executeScript("localStorage.removeItem('#{key}')") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 317 def removeSessionStorageItem(key) executeScript("sessionStorage.removeItem('#{key}')") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 430 def sendKeysToActiveElement(keys) sendKeysToElement(getActiveElement, keys) end
TODO - Implement file verification
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 435 def sendKeysToElement(element, keys) execute :elementSendKeys, {:id => element}, {:value => keys.join('').split(//)} end
Returns the current session ID.
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 121 def session_id @session_id || raise(Error::WebDriverError, "no current session exists") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 166 def setAlertValue(keys) execute :sendAlertText, {}, {:handler => 'prompt', :message => keys} end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 142 def setImplicitWaitTimeout(milliseconds) setTimeout('implicit', milliseconds) end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 301 def setLocalStorageItem(key, value) executeScript("localStorage.setItem('#{key}', '#{value}')") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 341 def setLocation(_lat, _lon, _alt) raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting location' end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 349 def setNetworkConnection(_type) raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting network connection' end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 499 def setScreenOrientation(orientation) execute :setScreenOrientation, {}, :orientation => orientation end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 146 def setScriptTimeout(milliseconds) setTimeout('script', milliseconds) end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 325 def setSessionStorageItem(key, value) executeScript("sessionStorage.setItem('#{key}', '#{value}')") end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 150 def setTimeout(type, milliseconds) execute :setTimeout, {}, :type => type, :ms => milliseconds end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 273 def setWindowPosition(_x, _y, _handle = nil) raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting the Window Position' end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 245 def setWindowSize(width, height, handle = :current) unless handle == :current raise Error::WebDriverError, 'Switch to desired window before changing its size' end execute :setWindowSize, {}, {:width => width, :height => height} end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 132 def status jwp = Selenium::WebDriver::Remote::Bridge::COMMANDS[:status] self.class.command(:status, jwp.first, jwp.last) execute :status end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 443 def submitElement(element) executeScript("var e = arguments[0].ownerDocument.createEvent('Event');" + "e.initEvent('submit', true, true);" + "if (arguments[0].dispatchEvent(e)) { arguments[0].submit() }", element) end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 213 def switchToDefaultContent switchToFrame nil end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 204 def switchToFrame(id) id = find_element_by('id', id) if id.is_a? String execute :switchToFrame, {}, :id => id end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 209 def switchToParentFrame execute :switchToParentFrame end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 200 def switchToWindow(name) execute :switchToWindow, {}, :handle => name end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 457 def touchDoubleTap(element) execute :touchDoubleTap, {}, :element => element end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 465 def touchDown(x, y) execute :touchDown, {}, :x => x, :y => y end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 491 def touchElementFlick(element, right_by, down_by, speed) execute :touchFlick, {}, :element => element, :xoffset => right_by, :yoffset => down_by, :speed => speed end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 487 def touchFlick(xspeed, yspeed) execute :touchFlick, {}, :xspeed => xspeed, :yspeed => yspeed end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 461 def touchLongPress(element) execute :touchLongPress, {}, :element => element end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 473 def touchMove(x, y) execute :touchMove, {}, :x => x, :y => y end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 477 def touchScroll(element, x, y) if element execute :touchScroll, {}, :element => element, :xoffset => x, :yoffset => y else execute :touchScroll, {}, :xoffset => x, :yoffset => y end end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 453 def touchSingleTap(element) execute :touchSingleTap, {}, :element => element end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 469 def touchUp(x, y) execute :touchUp, {}, :x => x, :y => y end
Private Instance Methods
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 597 def convert_locators(how, what) case how when 'class name' how = 'css selector' what = ".#{what}" when 'id' how = 'css selector' what = "##{what}" when 'name' how = 'css selector' what = "*[name='#{what}']" when 'tag name' how = 'css selector' end return how, what end
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 650 def escaper @escaper ||= defined?(URI::Parser) ? URI::Parser.new : URI end
executes a command on the remote server.
Returns the 'value' of the returned payload
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 621 def execute(*args) result = raw_execute(*args) result.payload.key?('value') ? result['value'] : result end
executes a command on the remote server.
@return [WebDriver::Remote::Response]
# File lib/selenium/webdriver/remote/w3c_bridge.rb, line 632 def raw_execute(command, opts = {}, command_hash = nil) verb, path = COMMANDS[command] || raise(ArgumentError, "unknown command: #{command.inspect}") path = path.dup path[':session_id'] = @session_id if path.include?(":session_id") begin opts.each { |key, value| path[key.inspect] = escaper.escape(value.to_s) } rescue IndexError raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}" end puts "-> #{verb.to_s.upcase} #{path}" if $DEBUG http.call verb, path, command_hash end