Class: Selenium::WebDriver::Safari::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/selenium/webdriver/safari/server.rb

Constant Summary collapse

HEADERS =
<<-HEADERS
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Server: safaridriver-ruby
HEADERS
HTML =
<<-HTML
<!DOCTYPE html>
<h2>SafariDriver requesting connection at %s</h2>
<script>
// Must wait for onload so the injected script is loaded by the
// SafariDriver extension.
window.onload = function() {
  window.postMessage({
    'type': 'connect',
    'origin': 'webdriver',
    'url': '%s'
  }, '*');
};
</script>
HTML

Instance Method Summary collapse

Constructor Details

#initialize(port, command_timeout) ⇒ Server

Returns a new instance of Server.



6
7
8
9
10
# File 'lib/selenium/webdriver/safari/server.rb', line 6

def initialize(port, command_timeout)
  @port  = port
  @command_timeout = command_timeout
  @frame = LibWebSocket::Frame.new
end

Instance Method Details

#process_handshakeObject



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/selenium/webdriver/safari/server.rb', line 108

def process_handshake
  @ws = @server.accept
  hs  = LibWebSocket::OpeningHandshake::Server.new

  req = ''
  until hs.done?
    data = @ws.getc || next
    req << data.chr

    unless hs.parse(data.chr)
      if req.include? "favicon.ico"
        @ws.close
        process_handshake
        return
      else
        raise Error::WebDriverError, "#{hs.error}: #{req}"
      end
    end
  end

  @ws.write(hs.to_s)
  @ws.flush

  puts "handshake complete" if $DEBUG
  @server.close
end

#process_initial_http_requestObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/selenium/webdriver/safari/server.rb', line 93

def process_initial_http_request
  http = @server.accept

  req = ''
  until req.include?("\r\n\r\n")
    req << http.read(1)
  end

  http << HEADERS
  http << "\r\n\r\n"
  http << HTML % [ws_uri, ws_uri]

  http.close
end

#receiveObject



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/selenium/webdriver/safari/server.rb', line 31

def receive
  until msg = @frame.next
    end_time = Time.now + @command_timeout

    begin
      data = @ws.read_nonblock(1)
    rescue Errno::EWOULDBLOCK, Errno::EAGAIN
      now = Time.now
      if now >= end_time
        raise Error::TimeOutError, "timed out waiting for Safari to respond"
      end

      IO.select([@ws], nil, nil, end_time - now)
      retry
    end

    @frame.append(data)
  end

  puts "<<< #{msg}" if $DEBUG

  WebDriver.json_load msg
end

#send(command) ⇒ Object



21
22
23
24
25
26
27
28
29
# File 'lib/selenium/webdriver/safari/server.rb', line 21

def send(command)
  json = WebDriver.json_dump(command)
  puts ">>> #{json}" if $DEBUG

  frame = LibWebSocket::Frame.new(json).to_s

  @ws.write frame
  @ws.flush
end

#startObject



12
13
14
# File 'lib/selenium/webdriver/safari/server.rb', line 12

def start
  @server = TCPServer.new(Platform.localhost, @port)
end

#stopObject



16
17
18
19
# File 'lib/selenium/webdriver/safari/server.rb', line 16

def stop
  @server.close if @server && !@server.closed?
  @ws.close if @ws && !@ws.closed?
end

#uriObject



59
60
61
# File 'lib/selenium/webdriver/safari/server.rb', line 59

def uri
  "http://#{Platform.localhost}:#{@port}"
end

#wait_for_connectionObject



63
64
65
66
67
# File 'lib/selenium/webdriver/safari/server.rb', line 63

def wait_for_connection
  # TODO: timeouts / non-blocking accept
  process_initial_http_request
  process_handshake
end

#ws_uriObject



55
56
57
# File 'lib/selenium/webdriver/safari/server.rb', line 55

def ws_uri
  "ws://#{Platform.localhost}:#{@port}/wd"
end