webdrivers 4.0.1 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,7 +31,7 @@ describe Webdrivers::Chromedriver do
31
31
  it 'does not download when offline, binary exists and matches major browser version' do
32
32
  allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
33
33
  allow(chromedriver).to receive(:exists?).and_return(true)
34
- allow(chromedriver).to receive(:chrome_version).and_return(Gem::Version.new('73.0.3683.68'))
34
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
35
35
  allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
36
36
 
37
37
  chromedriver.update
@@ -44,7 +44,7 @@ describe Webdrivers::Chromedriver do
44
44
 
45
45
  allow(Webdrivers::Network).to receive(:get_response).and_return(client_error)
46
46
  allow(chromedriver).to receive(:exists?).and_return(true)
47
- allow(chromedriver).to receive(:chrome_version).and_return(Gem::Version.new('73.0.3683.68'))
47
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
48
48
  allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
49
49
 
50
50
  chromedriver.update
@@ -55,7 +55,7 @@ describe Webdrivers::Chromedriver do
55
55
  it 'raises ConnectionError when offline, and binary does not match major browser version' do
56
56
  allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
57
57
  allow(chromedriver).to receive(:exists?).and_return(true)
58
- allow(chromedriver).to receive(:chrome_version).and_return(Gem::Version.new('73.0.3683.68'))
58
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
59
59
  allow(chromedriver).to receive(:current_version).and_return(Gem::Version.new('72.0.0.0'))
60
60
 
61
61
  msg = %r{Can not reach https://chromedriver.storage.googleapis.com}
@@ -108,7 +108,7 @@ describe Webdrivers::Chromedriver do
108
108
 
109
109
  it 'makes a network call if cached driver does not match the browser' do
110
110
  Webdrivers::System.cache_version('chromedriver', '71.0.3578.137')
111
- allow(chromedriver).to receive(:chrome_version).and_return(Gem::Version.new('73.0.3683.68'))
111
+ allow(chromedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
112
112
  allow(Webdrivers::Network).to receive(:get).and_return('73.0.3683.68')
113
113
  allow(Webdrivers::System).to receive(:download)
114
114
 
@@ -146,7 +146,7 @@ describe Webdrivers::Chromedriver do
146
146
  it 'returns a Gem::Version instance if binary is on the system' do
147
147
  allow(chromedriver).to receive(:exists?).and_return(true)
148
148
  allow(Webdrivers::System).to receive(:call)
149
- .with("#{chromedriver.driver_path} --version")
149
+ .with(chromedriver.driver_path, '--version')
150
150
  .and_return '71.0.3578.137'
151
151
 
152
152
  expect(chromedriver.current_version).to eq Gem::Version.new('71.0.3578.137')
@@ -155,19 +155,19 @@ describe Webdrivers::Chromedriver do
155
155
 
156
156
  describe '#latest_version' do
157
157
  it 'returns 2.41 if the browser version is less than 70' do
158
- allow(chromedriver).to receive(:chrome_version).and_return('69.0.0')
158
+ allow(chromedriver).to receive(:browser_version).and_return('69.0.0')
159
159
 
160
160
  expect(chromedriver.latest_version).to eq(Gem::Version.new('2.41'))
161
161
  end
162
162
 
163
163
  it 'returns the correct point release for a production version greater than 70' do
164
- allow(chromedriver).to receive(:chrome_version).and_return '71.0.3578.9999'
164
+ allow(chromedriver).to receive(:browser_version).and_return '71.0.3578.9999'
165
165
 
166
166
  expect(chromedriver.latest_version).to eq Gem::Version.new('71.0.3578.137')
167
167
  end
168
168
 
169
169
  it 'raises VersionError for beta version' do
170
- allow(chromedriver).to receive(:chrome_version).and_return('100.0.0')
170
+ allow(chromedriver).to receive(:browser_version).and_return('100.0.0')
171
171
  msg = 'Unable to find latest point release version for 100.0.0. '\
172
172
  'You appear to be using a non-production version of Chrome. '\
173
173
  'Please set `Webdrivers::Chromedriver.required_version = <desired driver version>` '\
@@ -177,7 +177,7 @@ describe Webdrivers::Chromedriver do
177
177
  end
178
178
 
179
179
  it 'raises VersionError for unknown version' do
180
- allow(chromedriver).to receive(:chrome_version).and_return('72.0.9999.0000')
180
+ allow(chromedriver).to receive(:browser_version).and_return('72.0.9999.0000')
181
181
  msg = 'Unable to find latest point release version for 72.0.9999. '\
182
182
  'Please set `Webdrivers::Chromedriver.required_version = <desired driver version>` '\
183
183
  'to a known chromedriver version: https://chromedriver.storage.googleapis.com/index.html'
@@ -253,8 +253,19 @@ describe Webdrivers::Chromedriver do
253
253
  describe '#driver_path' do
254
254
  it 'returns full location of binary' do
255
255
  expected_bin = "chromedriver#{'.exe' if Selenium::WebDriver::Platform.windows?}"
256
- expected_path = Webdrivers::System.escape_path("#{File.join(ENV['HOME'])}/.webdrivers/#{expected_bin}")
256
+ expected_path = File.absolute_path "#{File.join(ENV['HOME'])}/.webdrivers/#{expected_bin}"
257
257
  expect(chromedriver.driver_path).to eq(expected_path)
258
258
  end
259
259
  end
260
+
261
+ describe '#browser_version' do
262
+ it 'returns a Gem::Version object' do
263
+ expect(chromedriver.browser_version).to be_an_instance_of(Gem::Version)
264
+ end
265
+
266
+ it 'returns currently installed Chrome version' do
267
+ allow(Webdrivers::ChromeFinder).to receive(:version).and_return('72.0.0.0')
268
+ expect(chromedriver.browser_version).to be Gem::Version.new('72.0.0.0')
269
+ end
270
+ end
260
271
  end
@@ -0,0 +1,276 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Webdrivers::Edgedriver do
6
+ let(:edgedriver) { described_class }
7
+
8
+ before(:all) do # rubocop:disable RSpec/BeforeAfterAll
9
+ # Skip these tests if version of selenium-webdriver being tested with doesn't
10
+ # have Chromium based Edge support
11
+ unless defined?(Selenium::WebDriver::EdgeChrome)
12
+ skip "The current selenium-webdriver doesn't include Chromium based Edge support"
13
+ end
14
+ end
15
+
16
+ before { edgedriver.remove }
17
+
18
+ describe '#update' do
19
+ context 'when evaluating #correct_binary?' do
20
+ it 'does not download when latest version and current version match' do
21
+ allow(edgedriver).to receive(:latest_version).and_return(Gem::Version.new('72.0.0'))
22
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('72.0.0'))
23
+
24
+ edgedriver.update
25
+
26
+ expect(edgedriver.send(:exists?)).to be false
27
+ end
28
+
29
+ it 'does not download when offline, binary exists and is less than v70' do
30
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
31
+ allow(edgedriver).to receive(:exists?).and_return(true)
32
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new(69))
33
+
34
+ edgedriver.update
35
+
36
+ expect(File.exist?(edgedriver.driver_path)).to be false
37
+ end
38
+
39
+ it 'does not download when offline, binary exists and matches major browser version' do
40
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
41
+ allow(edgedriver).to receive(:exists?).and_return(true)
42
+ allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
43
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
44
+
45
+ edgedriver.update
46
+
47
+ expect(File.exist?(edgedriver.driver_path)).to be false
48
+ end
49
+
50
+ it 'does not download when get raises exception, binary exists and matches major browser version' do
51
+ client_error = instance_double(Net::HTTPNotFound, class: Net::HTTPNotFound, code: 404, message: '')
52
+
53
+ allow(Webdrivers::Network).to receive(:get_response).and_return(client_error)
54
+ allow(edgedriver).to receive(:exists?).and_return(true)
55
+ allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
56
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('73.0.3683.20'))
57
+
58
+ edgedriver.update
59
+
60
+ expect(File.exist?(edgedriver.driver_path)).to be false
61
+ end
62
+
63
+ it 'raises ConnectionError when offline, and binary does not match major browser version' do
64
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
65
+ allow(edgedriver).to receive(:exists?).and_return(true)
66
+ allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
67
+ allow(edgedriver).to receive(:current_version).and_return(Gem::Version.new('72.0.0.0'))
68
+
69
+ msg = %r{Can not reach https://msedgedriver.azureedge.net/}
70
+ expect { edgedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
71
+ end
72
+
73
+ it 'raises ConnectionError when offline, and no binary exists' do
74
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
75
+ allow(edgedriver).to receive(:exists?).and_return(false)
76
+
77
+ msg = %r{Can not reach https://msedgedriver.azureedge.net/}
78
+ expect { edgedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
79
+ end
80
+ end
81
+
82
+ context 'when correct binary is found' do
83
+ before { allow(edgedriver).to receive(:correct_binary?).and_return(true) }
84
+
85
+ it 'does not download' do
86
+ edgedriver.update
87
+
88
+ expect(edgedriver.current_version).to be_nil
89
+ end
90
+
91
+ it 'does not raise exception if offline' do
92
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
93
+
94
+ edgedriver.update
95
+
96
+ expect(edgedriver.current_version).to be_nil
97
+ end
98
+ end
99
+
100
+ context 'when correct binary is not found' do
101
+ before { allow(edgedriver).to receive(:correct_binary?).and_return(false) }
102
+
103
+ it 'downloads binary' do
104
+ edgedriver.update
105
+
106
+ expect(edgedriver.current_version).not_to be_nil
107
+ end
108
+
109
+ it 'raises ConnectionError if offline' do
110
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
111
+
112
+ msg = %r{Can not reach https://msedgedriver.azureedge.net/}
113
+ expect { edgedriver.update }.to raise_error(Webdrivers::ConnectionError, msg)
114
+ end
115
+ end
116
+
117
+ it 'makes a network call if cached driver does not match the browser' do
118
+ Webdrivers::System.cache_version('msedgedriver', '71.0.3578.137')
119
+ allow(edgedriver).to receive(:browser_version).and_return(Gem::Version.new('73.0.3683.68'))
120
+ allow(Webdrivers::Network).to receive(:get).and_return('73.0.3683.68'.encode('UTF-16'))
121
+ allow(Webdrivers::System).to receive(:download)
122
+
123
+ edgedriver.update
124
+
125
+ expect(Webdrivers::Network).to have_received(:get).once
126
+ end
127
+
128
+ context 'when required version is 0' do
129
+ it 'downloads the latest version' do
130
+ allow(edgedriver).to receive(:latest_version).and_return(Gem::Version.new('77.0.207.0'))
131
+ edgedriver.required_version = 0
132
+ edgedriver.update
133
+ expect(edgedriver.current_version.version).to eq('77.0.207.0')
134
+ end
135
+ end
136
+
137
+ context 'when required version is nil' do
138
+ it 'downloads the latest version' do
139
+ allow(edgedriver).to receive(:latest_version).and_return(Gem::Version.new('77.0.207.0'))
140
+ edgedriver.required_version = nil
141
+ edgedriver.update
142
+ expect(edgedriver.current_version.version).to eq('77.0.207.0')
143
+ end
144
+ end
145
+ end
146
+
147
+ describe '#current_version' do
148
+ it 'returns nil if binary does not exist on the system' do
149
+ allow(edgedriver).to receive(:driver_path).and_return('')
150
+
151
+ expect(edgedriver.current_version).to be_nil
152
+ end
153
+
154
+ it 'returns a Gem::Version instance if binary is on the system' do
155
+ allow(edgedriver).to receive(:exists?).and_return(true)
156
+ allow(Webdrivers::System).to receive(:call)
157
+ .with(edgedriver.driver_path, '--version')
158
+ .and_return '71.0.3578.137'
159
+
160
+ expect(edgedriver.current_version).to eq Gem::Version.new('71.0.3578.137')
161
+ end
162
+ end
163
+
164
+ describe '#latest_version' do
165
+ it 'returns the correct point release for a production version' do
166
+ allow(edgedriver).to receive(:browser_version).and_return '77.0.207.0'
167
+
168
+ expect(edgedriver.latest_version).to be_between(Gem::Version.new('77.0.207.0'), Gem::Version.new('78'))
169
+ end
170
+
171
+ it 'raises VersionError for beta version' do
172
+ allow(edgedriver).to receive(:browser_version).and_return('100.0.0')
173
+ msg = 'Unable to find latest point release version for 100.0.0. '\
174
+ 'You appear to be using a non-production version of Edge. '\
175
+ 'Please set `Webdrivers::Edgedriver.required_version = <desired driver version>` '\
176
+ 'to a known edgedriver version: Can not reach https://msedgedriver.azureedge.net/'
177
+
178
+ expect { edgedriver.latest_version }.to raise_exception(Webdrivers::VersionError, msg)
179
+ end
180
+
181
+ it 'raises VersionError for unknown version' do
182
+ skip "MS doesn't yet support point release latest versioning."
183
+ allow(edgedriver).to receive(:browser_version).and_return('77.0.9999.0000')
184
+ msg = 'Unable to find latest point release version for 77.0.9999. '\
185
+ 'Please set `Webdrivers::Edgedriver.required_version = <desired driver version>` '\
186
+ 'to a known edgedriver version: Can not reach https://msedgedriver.azureedge.net/'
187
+
188
+ expect { edgedriver.latest_version }.to raise_exception(Webdrivers::VersionError, msg)
189
+ end
190
+
191
+ it 'raises ConnectionError when offline' do
192
+ allow(Net::HTTP).to receive(:get_response).and_raise(SocketError)
193
+
194
+ msg = %r{^Can not reach https://msedgedriver.azureedge.net}
195
+ expect { edgedriver.latest_version }.to raise_error(Webdrivers::ConnectionError, msg)
196
+ end
197
+
198
+ it 'creates cached file' do
199
+ allow(edgedriver).to receive(:browser_version).and_return('77.0.207.0')
200
+ allow(Webdrivers::Network).to receive(:get).and_return('77.0.207.0'.encode('UTF-16'))
201
+
202
+ edgedriver.latest_version
203
+ expect(File.exist?("#{Webdrivers::System.install_dir}/msedgedriver.version")).to eq true
204
+ end
205
+
206
+ it 'does not make network call if cache is valid' do
207
+ allow(Webdrivers).to receive(:cache_time).and_return(3600)
208
+ Webdrivers::System.cache_version('msedgedriver', '77.0.207.0')
209
+ allow(Webdrivers::Network).to receive(:get)
210
+
211
+ expect(edgedriver.latest_version).to eq Gem::Version.new('77.0.207.0')
212
+
213
+ expect(Webdrivers::Network).not_to have_received(:get)
214
+ end
215
+
216
+ it 'makes a network call if cache is expired' do
217
+ Webdrivers::System.cache_version('msedgedriver', '71.0.3578.137')
218
+ allow(Webdrivers::Network).to receive(:get).and_return('77.0.207.0'.encode('UTF-16'))
219
+ allow(Webdrivers::System).to receive(:valid_cache?)
220
+ allow(edgedriver).to receive(:browser_version).and_return('77.0.207.0')
221
+
222
+ expect(edgedriver.latest_version).to eq Gem::Version.new('77.0.207.0')
223
+
224
+ expect(Webdrivers::Network).to have_received(:get)
225
+ expect(Webdrivers::System).to have_received(:valid_cache?)
226
+ end
227
+ end
228
+
229
+ describe '#required_version=' do
230
+ after { edgedriver.required_version = nil }
231
+
232
+ it 'returns the version specified as a Float' do
233
+ edgedriver.required_version = 73.0
234
+
235
+ expect(edgedriver.required_version).to eq Gem::Version.new('73.0')
236
+ end
237
+
238
+ it 'returns the version specified as a String' do
239
+ edgedriver.required_version = '73.0'
240
+
241
+ expect(edgedriver.required_version).to eq Gem::Version.new('73.0')
242
+ end
243
+ end
244
+
245
+ describe '#remove' do
246
+ it 'removes existing edgedriver' do
247
+ edgedriver.update
248
+
249
+ edgedriver.remove
250
+ expect(edgedriver.current_version).to be_nil
251
+ end
252
+
253
+ it 'does not raise exception if no edgedriver found' do
254
+ expect { edgedriver.remove }.not_to raise_error
255
+ end
256
+ end
257
+
258
+ describe '#driver_path' do
259
+ it 'returns full location of binary' do
260
+ expected_bin = "msedgedriver#{'.exe' if Selenium::WebDriver::Platform.windows?}"
261
+ expected_path = File.absolute_path "#{File.join(ENV['HOME'])}/.webdrivers/#{expected_bin}"
262
+ expect(edgedriver.driver_path).to eq(expected_path)
263
+ end
264
+ end
265
+
266
+ describe '#browser_version' do
267
+ it 'returns a Gem::Version object' do
268
+ expect(edgedriver.browser_version).to be_an_instance_of(Gem::Version)
269
+ end
270
+
271
+ it 'returns currently installed Edge version' do
272
+ allow(Webdrivers::EdgeFinder).to receive(:version).and_return('72.0.0.0')
273
+ expect(edgedriver.browser_version).to be Gem::Version.new('72.0.0.0')
274
+ end
275
+ end
276
+ end
@@ -112,7 +112,7 @@ testing/geckodriver in https://hg.mozilla.org/mozilla-central.
112
112
  This program is subject to the terms of the Mozilla Public License 2.0.
113
113
  You can obtain a copy of the license at https://mozilla.org/MPL/2.0/"
114
114
 
115
- allow(Webdrivers::System).to receive(:call).with("#{geckodriver.driver_path} --version").and_return return_value
115
+ allow(Webdrivers::System).to receive(:call).with(geckodriver.driver_path, '--version').and_return return_value
116
116
 
117
117
  expect(geckodriver.current_version).to eq Gem::Version.new('0.24.0')
118
118
  end
@@ -205,7 +205,7 @@ You can obtain a copy of the license at https://mozilla.org/MPL/2.0/"
205
205
  describe '#driver_path' do
206
206
  it 'returns full location of binary' do
207
207
  expected_bin = "geckodriver#{'.exe' if Selenium::WebDriver::Platform.windows?}"
208
- expected_path = Webdrivers::System.escape_path("#{File.join(ENV['HOME'])}/.webdrivers/#{expected_bin}")
208
+ expected_path = File.absolute_path "#{File.join(ENV['HOME'])}/.webdrivers/#{expected_bin}"
209
209
  expect(geckodriver.driver_path).to eq(expected_path)
210
210
  end
211
211
  end
@@ -87,7 +87,7 @@ describe Webdrivers::IEdriver do
87
87
 
88
88
  return_value = 'something IEDriverServer.exe 3.5.1 something else'
89
89
 
90
- allow(Webdrivers::System).to receive(:call).with("#{iedriver.driver_path} --version").and_return return_value
90
+ allow(Webdrivers::System).to receive(:call).with(iedriver.driver_path, '--version').and_return return_value
91
91
 
92
92
  expect(iedriver.current_version).to eq Gem::Version.new('3.5.1')
93
93
  end
@@ -186,7 +186,7 @@ describe Webdrivers::IEdriver do
186
186
 
187
187
  describe '#driver_path' do
188
188
  it 'returns full location of binary' do
189
- expected_path = Webdrivers::System.escape_path("#{File.join(ENV['HOME'])}/.webdrivers/IEDriverServer.exe")
189
+ expected_path = File.absolute_path "#{File.join(ENV['HOME'])}/.webdrivers/IEDriverServer.exe"
190
190
  expect(iedriver.driver_path).to eq(expected_path)
191
191
  end
192
192
  end
@@ -29,15 +29,15 @@ describe Webdrivers do
29
29
  end
30
30
 
31
31
  context 'when ENV variable WD_CACHE_TIME is set' do
32
- before { described_class.cache_time = 86_400 }
32
+ before { described_class.cache_time = 3600 }
33
33
 
34
- it 'uses cache time value from ENV variable over the Webdrivers.cache_time value' do
35
- allow(ENV).to receive(:[]).with('WD_CACHE_TIME').and_return(999)
36
- expect(described_class.cache_time).to be(999)
34
+ it 'uses cache time value from Webdrivers.cache_time over the ENV variable value' do
35
+ allow(ENV).to receive(:[]).with('WD_CACHE_TIME').and_return(900)
36
+ expect(described_class.cache_time).to be(3600)
37
37
  end
38
38
 
39
39
  it 'returns cache time as an Integer' do
40
- allow(ENV).to receive(:fetch).with('WD_CACHE_TIME', 86_400).and_return('999')
40
+ allow(ENV).to receive(:fetch).with('WD_CACHE_TIME', 3600).and_return('999')
41
41
  expect(described_class.cache_time).to be_an_instance_of(Integer)
42
42
  end
43
43
  end
@@ -70,5 +70,17 @@ describe Webdrivers do
70
70
  end
71
71
  end
72
72
  end
73
+
74
+ context 'when both ENV variable WD_INSTALL_DIR and Webdrivers.install_dir are set' do
75
+ it 'uses path from Webdrivers.install_dir' do
76
+ begin
77
+ described_class.install_dir = 'my_install_dir_path'
78
+ allow(ENV).to receive(:[]).with('WD_INSTALL_DIR').and_return('my_env_path')
79
+ expect(described_class.install_dir).to be('my_install_dir_path')
80
+ ensure
81
+ described_class.install_dir = nil
82
+ end
83
+ end
84
+ end
73
85
  end
74
86
  end
@@ -0,0 +1,17 @@
1
+ $downloadDevLink = "https://go.microsoft.com/fwlink/?linkid=2069324&Channel=Dev&language=en-us&Consent=0&IID=85213fc4-6a13-57ae-9082-72910982ede8"
2
+ $downloadCanaryLink = "https://go.microsoft.com/fwlink/?linkid=2084706&Channel=Canary&language=en-us&Consent=0&IID=85213fc4-6a13-57ae-9082-72910982ede8"
3
+ $devSetup = "C:\MicrosoftEdgeSetupDev.exe"
4
+ $canarySetup = "C:\MicrosoftEdgeSetupCanary.exe"
5
+
6
+ # Note: We're purposely skipping the -Wait flag in Start-Process.
7
+ # This is because Edge auto-launches after the setup is done and
8
+ # Start-Process continues to indefinitely wait on that process.
9
+ Write-Host "Installing Microsoft Edge (Dev)..." -ForegroundColor cyan
10
+ Invoke-WebRequest $downloadDevLink -OutFile $devSetup # Download Dev
11
+ Start-Process $devSetup # Run installer
12
+ Write-Host "Microsoft Edge (Dev) installed.`n" -ForegroundColor green
13
+
14
+ Write-Host "Installing Microsoft Edge (Canary)..." -ForegroundColor cyan
15
+ Invoke-WebRequest $downloadCanaryLink -OutFile $canarySetup # Download Canary
16
+ Start-Process $canarySetup # Run installer
17
+ Write-Host "Microsoft Edge (Canary) installed.`n" -ForegroundColor green