Class: Maze::Client::BrowserStackClientUtils
- Inherits:
-
Object
- Object
- Maze::Client::BrowserStackClientUtils
- Defined in:
- lib/maze/client/bs_client_utils.rb
Overview
Utils supporting the BrowserStack device farm integration
Class Method Summary collapse
-
.build_info(username, access_key, build_name) ⇒ Object
Gets the build/session info from BrowserStack.
- .download_log(username, access_key, name, log_url, log_type) ⇒ Object
-
.start_local_tunnel(bs_local, local_id, access_key) ⇒ Object
Starts the BrowserStack local tunnel.
-
.stop_local_tunnel ⇒ Object
Stops the local tunnel.
-
.upload_app(username, access_key, app, app_id_file = nil) ⇒ Object
Uploads an app to BrowserStack for later consumption.
Class Method Details
.build_info(username, access_key, build_name) ⇒ Object
Gets the build/session info from BrowserStack
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/maze/client/bs_client_utils.rb', line 113 def build_info(username, access_key, build_name) # Get the ID of a build uri = URI("https://api.browserstack.com/app-automate/builds.json?name=#{build_name}") request = Net::HTTP::Get.new(uri) request.basic_auth(username, access_key) res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| http.request(request) end build_info = JSON.parse(res.body) if !build_info.empty? build_id = build_info[0]['automation_build']['hashed_id'] # Get the build info uri = URI("https://api.browserstack.com/app-automate/builds/#{build_id}/sessions") request = Net::HTTP::Get.new(uri) request.basic_auth(username, access_key) res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| http.request(request) end build_json = JSON.parse(res.body) else raise "No build found for given ID: #{build_name}" end build_json end |
.download_log(username, access_key, name, log_url, log_type) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/maze/client/bs_client_utils.rb', line 149 def download_log(username, access_key, name, log_url, log_type) begin path = File.join(Dir.pwd, 'maze_output', log_type.to_s) FileUtils.makedirs(path) uri = URI(log_url) request = Net::HTTP::Get.new(uri) request.basic_auth(username, access_key) res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| http.request(request) end $logger.info "Saving #{log_type.to_s} log to #{path}/#{name}.log" File.open("#{path}/#{name}.log", 'w+') { |file| file.write(res.body) } rescue StandardError => e $logger.warn "Unable to save log from #{log_url}" $logger.warn e end end |
.start_local_tunnel(bs_local, local_id, access_key) ⇒ Object
Starts the BrowserStack local tunnel
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/maze/client/bs_client_utils.rb', line 83 def start_local_tunnel(bs_local, local_id, access_key) $logger.info 'Starting BrowserStack local tunnel' command = "#{bs_local} -d start --key #{access_key} --local-identifier #{local_id} " \ '--force-local --only-automate --force' # Extract the pid from the output so it gets killed at the end of the run output = Runner.run_command(command)[0][0] begin @pid = JSON.parse(output)['pid'] $logger.info "BrowserStackLocal daemon running under pid #{@pid}" rescue JSON::ParserError $logger.warn 'Unable to parse pid from output, BrowserStackLocal will be left to die its own death' end end |
.stop_local_tunnel ⇒ Object
Stops the local tunnel
99 100 101 102 103 104 105 106 107 |
# File 'lib/maze/client/bs_client_utils.rb', line 99 def stop_local_tunnel if @pid $logger.info "Stopping BrowserStack local tunnel" Process.kill('TERM', @pid) @pid = nil end rescue Errno::ESRCH # ignored end |
.upload_app(username, access_key, app, app_id_file = nil) ⇒ Object
Uploads an app to BrowserStack for later consumption
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/maze/client/bs_client_utils.rb', line 15 def upload_app(username, access_key, app, app_id_file=nil) if app.start_with? 'bs://' app_url = app $logger.info "Using pre-uploaded app from #{app}" else = Maze::Helper.(app) uri = URI('https://api-cloud.browserstack.com/app-automate/upload') request = Net::HTTP::Post.new(uri) request.basic_auth(username, access_key) request.set_form({ 'file' => File.new(, 'rb') }, 'multipart/form-data') upload_tries = 0 allowed_tries = 10 while upload_tries < allowed_tries begin $logger.info "Uploading app: #{}" res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http| http.request(request) end body = res.body response = JSON.parse body if response.include?('error') $logger.error "Upload failed due to error: #{response['error']}" elsif !response.include?('app_url') $logger.error "Upload failed, response did not include an app_url: #{res}" else # Successful upload break end rescue Net::ReadTimeout => error Bugsnag.notify error $logger.error "Upload failed due to ReadTimeout" rescue JSON::ParserError => error Bugsnag.notify error $logger.error "Unexpected JSON response, received: #{body}" end upload_tries += 1 if upload_tries < allowed_tries $logger.info 'Retrying upload in 60s' Kernel::sleep 60 end end if response.nil? || response.include?('error') || !response.include?('app_url') raise "Failed to upload app after #{upload_tries} attempts" end app_url = response['app_url'] $logger.info "App uploaded to: #{app_url}" $logger.info 'You can use this url to avoid uploading the same app more than once.' end unless app_id_file.nil? $logger.info "Writing uploaded app url to #{app_id_file}" File.write(Maze::Helper.(app_id_file), app_url) end app_url end |