testcentricity_web 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 413fc537c154be3f2dcf1b31d68f4e9b03de600b
4
- data.tar.gz: 0ab45a3cc3c49aee5d327a93efccac581bb6e125
3
+ metadata.gz: 2100edbdb7c76973477b24ce275d367a891c2108
4
+ data.tar.gz: 5ccc3816ad3410aee17fa7c951a121cedf203f8c
5
5
  SHA512:
6
- metadata.gz: 838e99e3be15fda4e31b9635114292fe58c490d92dadb273b25c2c89cc41c0272509fdebf23fa0131e94f66a2bca7f2cd6f6c8a545569bc142f4a8942e3f09f2
7
- data.tar.gz: 19100004c7508f79d8d36b4607613faf63562d0f3ad178d015f54a3d7b13e6c39ec4e5db8996f545803de5a02fb6055c95b4d89707eb88e9402e08c733f48af0
6
+ metadata.gz: 19137aed8261b00966dd2ea81325eb005ef7167d1086e837aab76d5e5d71d7c92a89990d2bf9eafb23c537784c165d667c5c0360c1fa5568159285c543f85036
7
+ data.tar.gz: 2b3c95326197d5910f78ed5a2c1eeabdd26a68b1286d1ac3f393f92e0f439b9f84d3c9f01bccf0d42c99ed21427056e57f9bb2a1ff4e5482b7097593240b8362
data/README.md CHANGED
@@ -357,24 +357,29 @@ To maximize a desktop browser window, you set the `BROWSER_SIZE` Environment Var
357
357
 
358
358
  ### Locally hosted emulated mobile web browser
359
359
 
360
- You can also run your tests against emulated mobile device browsers within a locally hosted instance of a Firefox (default) or Chrome desktop browser.
361
- The specified mobile browser's user agent and default screen resolution and orientation will be automatically set in the local Firefox or Chrome browser
362
- instance. You may even specify the emulated device's screen orientation. For locally hosted emulated mobile web browsers, the `WEB_BROWSER` Environment
363
- Variable must be set to one of the values from the table below:
364
-
365
- `WEB_BROWSER` | `HOST_BROWSER`
366
- --------------- |------------
367
- `ipad` |`firefox` (default) or `chrome`
368
- `ipad_pro` |`firefox` (default) or `chrome`
369
- `iphone` |`firefox` (default) or `chrome`
370
- `iphone4` |`firefox` (default) or `chrome`
371
- `iphone5` |`firefox` (default) or `chrome`
372
- `iphone6` |`firefox` (default) or `chrome`
373
- `iphone6_plus` |`firefox` (default) or `chrome`
374
- `android_phone` |`firefox` (default) or `chrome`
375
- `android_tablet` |`firefox` (default) or `chrome`
376
- `windows_phone7` |`firefox` (default) or `chrome`
377
- `windows_phone8` |`firefox` (default) or `chrome`
360
+ You can also run your tests against emulated mobile device browsers within a locally hosted instance of a Firefox or Chrome desktop browser. The
361
+ specified mobile browser's user agent and default CSS screen dimensions and orientation will be automatically set in the local Firefox or Chrome
362
+ browser instance. You may even specify the emulated device's screen orientation. For locally hosted emulated mobile web browsers, the `WEB_BROWSER`
363
+ Environment Variable must be set to one of the values from the table below:
364
+
365
+ `WEB_BROWSER` | `HOST_BROWSER` | **Default CSS Screen Dimensions** | **Default Orientation**
366
+ --------------|----------------|-------------------------------|-------------------
367
+ `ipad` |`firefox` or `chrome` |1024, 768|landscape
368
+ `ipad_pro` |`firefox` or `chrome` |1366, 1024|landscape
369
+ `android_tablet` |`firefox` or `chrome` |1024, 768|landscape
370
+ `kindle_fire` |`firefox` or `chrome` |1024, 600|landscape
371
+ `kindle_firehd7` |`firefox` or `chrome` |800, 480|landscape
372
+ `kindle_firehd8` |`firefox` or `chrome` |1280, 800|landscape
373
+ `surface` |`firefox` or `chrome` |1366, 768|landscape
374
+ `blackberry_playbook` |`firefox` or `chrome` |1024, 600|landscape
375
+ `iphone` |`firefox` or `chrome` |320, 480|portrait
376
+ `iphone4` |`firefox` or `chrome` |320, 480|portrait
377
+ `iphone5` |`firefox` or `chrome` |320, 568|portrait
378
+ `iphone6` |`firefox` or `chrome` |375, 667|portrait
379
+ `iphone6_plus` |`firefox` or `chrome` |414, 736|portrait
380
+ `android_phone` |`firefox` or `chrome` |320, 480|portrait
381
+ `windows_phone7` |`firefox` or `chrome` |320, 480|portrait
382
+ `windows_phone8` |`firefox` or `chrome` |320, 480|portrait
378
383
 
379
384
  To specify the emulated device's screen orientation, you set the `ORIENTATION` Environment Variable to either `portrait` or `landscape`.
380
385
 
@@ -540,17 +545,22 @@ replace the placeholder text with your user account and authorization code for t
540
545
  # NOTE: to host emulated mobile browsers in Chrome set the HOST_BROWSER=chrome
541
546
  #==============
542
547
 
543
- ipad: WEB_BROWSER=ipad HOST_BROWSER=firefox <%= mobile %>
544
- ipad_pro: WEB_BROWSER=ipad_pro HOST_BROWSER=firefox <%= mobile %>
545
- iphone: WEB_BROWSER=iphone HOST_BROWSER=firefox <%= mobile %>
546
- iphone4: WEB_BROWSER=iphone4 HOST_BROWSER=firefox <%= mobile %>
547
- iphone5: WEB_BROWSER=iphone5 HOST_BROWSER=firefox <%= mobile %>
548
- iphone6: WEB_BROWSER=iphone6 HOST_BROWSER=firefox <%= mobile %>
549
- iphone6_plus: WEB_BROWSER=iphone6_plus HOST_BROWSER=firefox <%= mobile %>
550
- android_phone: WEB_BROWSER=android_phone HOST_BROWSER=firefox <%= mobile %>
551
- android_tablet: WEB_BROWSER=android_tablet HOST_BROWSER=firefox <%= mobile %>
552
- windows_phone7: WEB_BROWSER=windows_phone7 HOST_BROWSER=firefox <%= mobile %>
553
- windows_phone8: WEB_BROWSER=windows_phone8 HOST_BROWSER=firefox <%= mobile %>
548
+ ipad: WEB_BROWSER=ipad HOST_BROWSER=firefox <%= mobile %>
549
+ ipad_pro: WEB_BROWSER=ipad_pro HOST_BROWSER=firefox <%= mobile %>
550
+ iphone: WEB_BROWSER=iphone HOST_BROWSER=firefox <%= mobile %>
551
+ iphone4: WEB_BROWSER=iphone4 HOST_BROWSER=firefox <%= mobile %>
552
+ iphone5: WEB_BROWSER=iphone5 HOST_BROWSER=firefox <%= mobile %>
553
+ iphone6: WEB_BROWSER=iphone6 HOST_BROWSER=firefox <%= mobile %>
554
+ iphone6_plus: WEB_BROWSER=iphone6_plus HOST_BROWSER=firefox <%= mobile %>
555
+ android_phone: WEB_BROWSER=android_phone HOST_BROWSER=firefox <%= mobile %>
556
+ android_tablet: WEB_BROWSER=android_tablet HOST_BROWSER=firefox <%= mobile %>
557
+ kindle_fire: WEB_BROWSER=kindle_fire HOST_BROWSER=firefox <%= mobile %>
558
+ kindle_firehd7: WEB_BROWSER=kindle_firehd7 HOST_BROWSER=firefox <%= mobile %>
559
+ kindle_firehd8: WEB_BROWSER=kindle_firehd8 HOST_BROWSER=firefox <%= mobile %>
560
+ surface: WEB_BROWSER=surface HOST_BROWSER=firefox <%= mobile %>
561
+ blackberry_playbook: WEB_BROWSER=blackberry_playbook HOST_BROWSER=firefox <%= mobile %>
562
+ windows_phone7: WEB_BROWSER=windows_phone7 HOST_BROWSER=firefox <%= mobile %>
563
+ windows_phone8: WEB_BROWSER=windows_phone8 HOST_BROWSER=firefox <%= mobile %>
554
564
 
555
565
 
556
566
  #==============
@@ -112,34 +112,44 @@ module TestCentricity
112
112
  private
113
113
 
114
114
  def self.device_agents
115
- devices = { :iphone => "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
116
- :iphone4 => "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
117
- :iphone5 => "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
118
- :iphone6 => "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
119
- :iphone6_plus => "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
120
- :ipad => "Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/3B143 Safari/601.1",
121
- :ipad_pro => "Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1",
122
- :android_phone => "Mozilla/5.0 (Linux; U; Android 4.0.1; en-us; sdk Build/ICS_MR0) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
123
- :android_tablet => "Mozilla/5.0 (Linux; U; Android 3.0; en-us; GT-P7100 Build/HRI83) AppleWebkit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13",
124
- :windows_phone10 => "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; DEVICE INFO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Mobile Safari/537.36 Edge/12.0",
125
- :windows_phone8 => "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)",
126
- :windows_phone7 => "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; NOKIA; Lumia 710)"
115
+ devices = { :iphone => "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
116
+ :iphone4 => "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
117
+ :iphone5 => "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
118
+ :iphone6 => "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
119
+ :iphone6_plus => "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
120
+ :ipad => "Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/3B143 Safari/601.1",
121
+ :ipad_pro => "Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B137 Safari/601.1",
122
+ :android_phone => "Mozilla/5.0 (Linux; U; Android 4.0.1; en-us; sdk Build/ICS_MR0) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
123
+ :android_tablet => "Mozilla/5.0 (Linux; U; Android 3.0; en-us; GT-P7100 Build/HRI83) AppleWebkit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13",
124
+ :kindle_fire => "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.0.141.16-Gen4_11004310) AppleWebkit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true",
125
+ :kindle_firehd7 => "Mozilla/5.0 (Linux; U; en-us; KFTHWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true",
126
+ :kindle_firehd8 => "Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true",
127
+ :windows_phone10 => "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; DEVICE INFO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Mobile Safari/537.36 Edge/12.0",
128
+ :windows_phone8 => "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)",
129
+ :windows_phone7 => "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; NOKIA; Lumia 710)",
130
+ :surface => "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch)",
131
+ :blackberry_playbook => "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+"
127
132
  }
128
133
  devices
129
134
  end
130
135
 
131
136
  def self.device_sizes
132
- sizes = { :iphone => [320, 568, :portrait],
133
- :iphone4 => [320, 480, :portrait],
134
- :iphone5 => [320, 568, :portrait],
135
- :iphone6 => [375, 667, :portrait],
136
- :iphone6_plus => [414, 736, :portrait],
137
- :ipad => [1024, 768, :landscape],
138
- :ipad_pro => [1366, 1024, :landscape],
139
- :android_phone => [320, 480, :portrait],
140
- :android_tablet => [1024, 768, :landscape],
141
- :windows_phone8 => [320, 480, :portrait],
142
- :windows_phone7 => [320, 480, :portrait]
137
+ sizes = { :iphone => [320, 480, :portrait],
138
+ :iphone4 => [320, 480, :portrait],
139
+ :iphone5 => [320, 568, :portrait],
140
+ :iphone6 => [375, 667, :portrait],
141
+ :iphone6_plus => [414, 736, :portrait],
142
+ :android_phone => [320, 480, :portrait],
143
+ :windows_phone8 => [320, 480, :portrait],
144
+ :windows_phone7 => [320, 480, :portrait],
145
+ :ipad => [1024, 768, :landscape],
146
+ :ipad_pro => [1366, 1024, :landscape],
147
+ :android_tablet => [1024, 768, :landscape],
148
+ :kindle_fire => [1024, 600, :landscape],
149
+ :kindle_firehd7 => [800, 480, :landscape],
150
+ :kindle_firehd8 => [1280, 800, :landscape],
151
+ :surface => [1366, 768, :landscape],
152
+ :blackberry_playbook => [1024, 600, :landscape]
143
153
  }
144
154
  sizes
145
155
  end
@@ -7,5 +7,31 @@ module TestCentricity
7
7
  @type = :image
8
8
  @alt_locator = nil
9
9
  end
10
+
11
+ # Is image loaded?
12
+ #
13
+ # @return [Boolean]
14
+ # @example
15
+ # company_logo_image.is_loaded??
16
+ #
17
+ def is_loaded?
18
+ obj, _ = find_element
19
+ object_not_found_exception(obj, nil)
20
+ obj.native.attribute('complete')
21
+ end
22
+ end
23
+
24
+ # Wait until the image is fully loaded, or until the specified wait time has expired.
25
+ #
26
+ # @param seconds [Integer or Float] wait time in seconds
27
+ # @example
28
+ # company_logo_image.wait_until_loaded(5)
29
+ #
30
+ def wait_until_loaded(seconds = nil)
31
+ timeout = seconds.nil? ? Capybara.default_max_wait_time : seconds
32
+ wait = Selenium::WebDriver::Wait.new(timeout: timeout)
33
+ wait.until { is_loaded? }
34
+ rescue
35
+ raise "Image #{@locator} failed to load within #{timeout} seconds" unless is_loaded?
10
36
  end
11
37
  end
@@ -222,7 +222,7 @@ module TestCentricity
222
222
  wait = Selenium::WebDriver::Wait.new(timeout: timeout)
223
223
  wait.until { get_value == value }
224
224
  rescue
225
- raise "Value of UI element #{@locator} failed to equal '#{value}' after #{timeout} seconds" unless exists?
225
+ raise "Value of UI element #{@locator} failed to equal '#{value}' after #{timeout} seconds" unless get_value == value
226
226
  end
227
227
 
228
228
  # Wait until the object's value changes to a different value, or until the specified wait time has expired.
@@ -237,7 +237,7 @@ module TestCentricity
237
237
  wait = Selenium::WebDriver::Wait.new(timeout: timeout)
238
238
  wait.until { get_value != value }
239
239
  rescue
240
- raise "Value of UI element #{@locator} failed to change from '#{value}' after #{timeout} seconds" unless exists?
240
+ raise "Value of UI element #{@locator} failed to change from '#{value}' after #{timeout} seconds" if get_value == value
241
241
  end
242
242
 
243
243
  def get_value(visible = true)
@@ -1,3 +1,3 @@
1
1
  module TestCentricityWeb
2
- VERSION = '0.8.0'
2
+ VERSION = '0.8.1'
3
3
  end
@@ -6,6 +6,7 @@ module TestCentricity
6
6
  include Capybara::DSL
7
7
 
8
8
  def self.initialize_web_driver(app_host = nil)
9
+ Capybara.app_host = app_host unless app_host.nil?
9
10
  browser = ENV['WEB_BROWSER']
10
11
 
11
12
  # assume that we're testing within a local desktop web browser
@@ -29,22 +30,8 @@ module TestCentricity
29
30
  initialize_local_browser(browser)
30
31
  end
31
32
 
32
- Capybara.app_host = app_host unless app_host.nil?
33
-
34
33
  # set browser window size only if testing with a desktop web browser
35
- unless Capybara.current_driver == :poltergeist
36
- if Environ.is_desktop?
37
- if ENV['BROWSER_SIZE'] == 'max'
38
- Browsers.maximize_browser
39
- elsif ENV['BROWSER_SIZE']
40
- Browsers.set_browser_window_size(ENV['BROWSER_SIZE'])
41
- else
42
- Browsers.set_browser_window_size(Browsers.browser_size(browser, ENV['ORIENTATION']))
43
- end
44
- elsif Environ.is_mobile? && !Environ.is_device?
45
- Browsers.set_browser_window_size(Browsers.browser_size(browser, ENV['ORIENTATION']))
46
- end
47
- end
34
+ initialize_browser_size(browser) unless Capybara.current_driver == :poltergeist
48
35
 
49
36
  puts "Using #{Environ.browser.to_s} browser"
50
37
  end
@@ -57,7 +44,7 @@ module TestCentricity
57
44
  case browser.downcase.to_sym
58
45
  when :firefox, :chrome, :ie, :safari, :edge
59
46
  Capybara::Selenium::Driver.new(app, :browser => browser.to_sym)
60
- when :iphone, :iphone5, :iphone6, :iphone6_plus, :ipad, :ipad_pro, :android_phone, :android_tablet, :windows_phone7, :windows_phone8
47
+ when :iphone, :iphone5, :iphone6, :iphone6_plus, :ipad, :ipad_pro, :android_phone, :android_tablet, :windows_phone7, :windows_phone8, :kindle_fire, :kindle_firehd7, :kindle_firehd8, :surface, :blackberry_playbook
61
48
  Environ.set_platform(:mobile)
62
49
  ENV['HOST_BROWSER'] ? host_browser = ENV['HOST_BROWSER'].downcase.to_sym : host_browser = :firefox
63
50
  case host_browser
@@ -233,5 +220,19 @@ module TestCentricity
233
220
  Capybara.run_server = false
234
221
 
235
222
  end
223
+
224
+ def self.initialize_browser_size(browser)
225
+ if Environ.is_desktop?
226
+ if ENV['BROWSER_SIZE'] == 'max'
227
+ Browsers.maximize_browser
228
+ elsif ENV['BROWSER_SIZE']
229
+ Browsers.set_browser_window_size(ENV['BROWSER_SIZE'])
230
+ else
231
+ Browsers.set_browser_window_size(Browsers.browser_size(browser, ENV['ORIENTATION']))
232
+ end
233
+ elsif Environ.is_mobile? && !Environ.is_device?
234
+ Browsers.set_browser_window_size(Browsers.browser_size(browser, ENV['ORIENTATION']))
235
+ end
236
+ end
236
237
  end
237
238
  end
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.email = ['test_automation@icloud.com']
13
13
  spec.summary = %q{A Page Object and Data Object Model Framework for desktop and mobile web testing}
14
14
  spec.description = %q{
15
- TestCentricity™ core generic framework for desktop and mobile web site testing implements a Page Object Model DSL,
15
+ TestCentricity™ core generic framework for desktop and mobile web site testing implements a Page Object Model DSL
16
16
  for use with Cucumber, Capybara, and Selenium-Webdriver. Supports testing against locally hosted desktop browsers
17
17
  (Firefox, Chrome, Safari, IE, or Edge), locally hosted emulated iOS and Android mobile browsers (using Firefox or
18
18
  Chrome), a "headless" browser (using Poltergeist and PhantomJS), or on cloud hosted browsers using the BrowserStack,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: testcentricity_web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - A.J. Mrozinski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-21 00:00:00.000000000 Z
11
+ date: 2016-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -144,7 +144,7 @@ dependencies:
144
144
  version: 1.1.1
145
145
  description: |2-
146
146
 
147
- TestCentricity™ core generic framework for desktop and mobile web site testing implements a Page Object Model DSL,
147
+ TestCentricity™ core generic framework for desktop and mobile web site testing implements a Page Object Model DSL
148
148
  for use with Cucumber, Capybara, and Selenium-Webdriver. Supports testing against locally hosted desktop browsers
149
149
  (Firefox, Chrome, Safari, IE, or Edge), locally hosted emulated iOS and Android mobile browsers (using Firefox or
150
150
  Chrome), a "headless" browser (using Poltergeist and PhantomJS), or on cloud hosted browsers using the BrowserStack,