Path: blob/trunk/rb/spec/unit/selenium/webdriver/chrome/options_spec.rb
4103 views
# frozen_string_literal: true12# Licensed to the Software Freedom Conservancy (SFC) under one3# or more contributor license agreements. See the NOTICE file4# distributed with this work for additional information5# regarding copyright ownership. The SFC licenses this file6# to you under the Apache License, Version 2.0 (the7# "License"); you may not use this file except in compliance8# with the License. You may obtain a copy of the License at9#10# http://www.apache.org/licenses/LICENSE-2.011#12# Unless required by applicable law or agreed to in writing,13# software distributed under the License is distributed on an14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY15# KIND, either express or implied. See the License for the16# specific language governing permissions and limitations17# under the License.1819require File.expand_path('../spec_helper', __dir__)2021module Selenium22module WebDriver23module Chrome24describe Options do25subject(:options) { described_class.new }2627describe '#initialize' do28it 'accepts defined parameters' do29allow(File).to receive(:file?).and_return(true)3031opts = described_class.new(browser_version: '75',32platform_name: 'win10',33accept_insecure_certs: false,34page_load_strategy: 'eager',35unhandled_prompt_behavior: 'accept',36strict_file_interactability: true,37timeouts: {script: 40000,38page_load: 400000,39implicit: 1},40set_window_rect: false,41args: %w[foo bar],42prefs: {foo: 'bar'},43binary: '/foo/bar',44extensions: ['foo.crx', 'bar.crx'],45encoded_extensions: ['encoded_foobar'],46foo: 'bar',47emulation: {device_name: :bar},48local_state: {foo: 'bar'},49detach: true,50debugger_address: '127.0.0.1:8181',51exclude_switches: %w[foobar barfoo],52minidump_path: 'linux/only',53perf_logging_prefs: {enable_network: true},54window_types: %w[normal devtools],55android_package: 'package',56android_activity: 'activity',57android_device_serial: '123',58android_use_running_app: true,59'custom:options': {foo: 'bar'})6061expect(opts.args).to eq(%w[foo bar])62expect(opts.prefs[:foo]).to eq('bar')63expect(opts.binary).to eq('/foo/bar')64expect(opts.extensions).to eq(['foo.crx', 'bar.crx'])65expect(opts.instance_variable_get(:@options)[:foo]).to eq('bar')66expect(opts.emulation[:device_name]).to eq(:bar)67expect(opts.local_state[:foo]).to eq('bar')68expect(opts.detach).to be(true)69expect(opts.debugger_address).to eq('127.0.0.1:8181')70expect(opts.exclude_switches).to eq(%w[foobar barfoo])71expect(opts.minidump_path).to eq('linux/only')72expect(opts.perf_logging_prefs[:enable_network]).to be(true)73expect(opts.window_types).to eq(%w[normal devtools])74expect(opts.browser_name).to eq('chrome')75expect(opts.browser_version).to eq('75')76expect(opts.platform_name).to eq('win10')77expect(opts.accept_insecure_certs).to be(false)78expect(opts.page_load_strategy).to eq('eager')79expect(opts.unhandled_prompt_behavior).to eq('accept')80expect(opts.strict_file_interactability).to be(true)81expect(opts.timeouts).to eq(script: 40000, page_load: 400000, implicit: 1)82expect(opts.set_window_rect).to be(false)83expect(opts.android_package).to eq('package')84expect(opts.android_activity).to eq('activity')85expect(opts.android_device_serial).to eq('123')86expect(opts.android_use_running_app).to be(true)87expect(opts.options[:'custom:options']).to eq(foo: 'bar')88end89end9091describe 'accessors' do92it 'adds a command-line argument' do93options.args << 'foo'94expect(options.args).to eq(['foo'])95end9697it 'adds an extension' do98allow(File).to receive(:file?).and_return(true)99ext = 'foo.crx'100allow_any_instance_of(described_class)101.to receive(:encode_file).with(ext).and_return("encoded_#{ext[/([^.]*)/]}")102103options.extensions << ext104expect(options.extensions).to eq([ext])105end106107it 'sets the binary path' do108options.binary = '/foo/bar'109expect(options.binary).to eq('/foo/bar')110end111112it 'adds a preference' do113options.prefs[:foo] = 'bar'114expect(options.prefs[:foo]).to eq('bar')115end116117it 'add an emulated device by name' do118options.emulation[:device_name] = 'iPhone 6'119expect(options.emulation).to eq(device_name: 'iPhone 6')120end121122it 'adds local state' do123options.local_state[:foo] = 'bar'124expect(options.local_state).to eq(foo: 'bar')125end126127it 'adds a switch to exclude' do128options.exclude_switches << 'exclude-this'129expect(options.exclude_switches).to eq(['exclude-this'])130end131132it 'adds performance logging preferences' do133options.perf_logging_prefs[:enable_network] = true134expect(options.perf_logging_prefs).to eq(enable_network: true)135end136137it 'adds a window type' do138options.window_types << 'normal'139expect(options.window_types).to eq(['normal'])140end141end142143describe '#enable_bidi!' do144it 'allows setting and querying bidi' do145expect(options.web_socket_url).to be_nil146expect(options.bidi?).to be false147148options.enable_bidi!149150expect(options.bidi?).to be true151expect(options.web_socket_url).to be true152end153end154155describe '#add_extension' do156it 'adds an extension' do157allow(File).to receive(:file?).and_return(true)158ext = 'foo.crx'159allow_any_instance_of(described_class)160.to receive(:encode_file).with(ext).and_return("encoded_#{ext[/([^.]*)/]}")161162options.add_extension(ext)163expect(options.extensions).to eq([ext])164end165166it 'raises error when the extension file is missing' do167allow(File).to receive(:file?).with('/foo/bar').and_return false168169expect { options.add_extension('/foo/bar') }.to raise_error(Error::WebDriverError)170end171172it 'raises error when the extension file is not .crx' do173allow(File).to receive(:file?).with('/foo/bar').and_return true174175expect { options.add_extension('/foo/bar') }.to raise_error(Error::WebDriverError)176end177end178179describe '#add_encoded_extension' do180it 'adds an encoded extension' do181options.add_encoded_extension('foo')182expect(options.instance_variable_get(:@encoded_extensions)).to include('foo')183end184end185186describe '#add_argument' do187it 'adds a command-line argument' do188options.add_argument('foo')189expect(options.args).to eq(['foo'])190end191end192193describe '#add_option' do194it 'adds vendor namespaced options with ordered pairs' do195options.add_option('foo:bar', {bar: 'foo'})196expect(options.instance_variable_get(:@options)['foo:bar']).to eq({bar: 'foo'})197end198199it 'adds vendor namespaced options with Hash' do200options.add_option('foo:bar' => {bar: 'foo'})201expect(options.instance_variable_get(:@options)['foo:bar']).to eq({bar: 'foo'})202end203end204205describe '#add_preference' do206it 'adds a preference' do207options.add_preference(:foo, 'bar')208expect(options.prefs[:foo]).to eq('bar')209end210end211212describe '#add_emulation' do213it 'add an emulated device by name' do214options.add_emulation(device_name: 'iPhone 6')215expect(options.emulation).to eq(device_name: 'iPhone 6')216end217218it 'adds emulated device metrics' do219options.add_emulation(device_metrics: {width: 400})220expect(options.emulation).to eq(device_metrics: {width: 400})221end222223it 'adds emulated user agent' do224options.add_emulation(user_agent: 'foo')225expect(options.emulation).to eq(user_agent: 'foo')226end227end228229describe '#enable_android' do230it 'adds default android settings' do231options.enable_android232233expect(options.android_package).to eq('com.android.chrome')234expect(options.android_activity).to be_nil235expect(options.android_device_serial).to be_nil236expect(options.android_use_running_app).to be_nil237end238239it 'accepts parameters' do240options.enable_android(package: 'foo',241serial_number: '123',242activity: 'qualified',243use_running_app: true)244expect(options.android_package).to eq('foo')245expect(options.android_activity).to eq('qualified')246expect(options.android_device_serial).to eq('123')247expect(options.android_use_running_app).to be(true)248end249end250251describe '#as_json' do252it 'returns empty options by default' do253expect(options.as_json).to eq('browserName' => 'chrome', 'goog:chromeOptions' => {})254end255256it 'errors when unrecognized capability is passed' do257options.add_option(:foo, 'bar')258259expect {260options.as_json261}.to raise_error(Error::WebDriverError, /These options are not w3c compliant: \{:?foo[:=][ >]"bar"\}/)262end263264it 'returns added options' do265options.add_option('foo:bar', {foo: 'bar'})266expect(options.as_json).to eq('browserName' => 'chrome',267'foo:bar' => {'foo' => 'bar'},268'goog:chromeOptions' => {})269end270271it 'converts profile' do272profile = Profile.new273directory = profile.directory274275opts = described_class.new(profile: profile)276expect(opts.as_json).to eq('browserName' => 'chrome',277'goog:chromeOptions' =>278{'args' => ["--user-data-dir=#{directory}"]})279end280281it 'processes unhandled_prompt_behavior hash values' do282opts = described_class.new(unhandled_prompt_behavior: {283alert: :accept_and_notify,284confirm: 'dismiss_and_notify',285prompt: :ignore,286before_unload: 'accept',287default: :dismiss288})289290expect(opts.as_json).to eq('browserName' => 'chrome',291'unhandledPromptBehavior' => {292'alert' => 'accept and notify',293'confirm' => 'dismiss and notify',294'prompt' => 'ignore',295'beforeUnload' => 'accept',296'default' => 'dismiss'297},298'goog:chromeOptions' => {})299end300301it 'returns a JSON hash' do302allow(File).to receive(:file?).and_return(true)303allow_any_instance_of(described_class)304.to receive(:encode_extension).with('foo.crx').and_return('encoded_foo')305allow_any_instance_of(described_class)306.to receive(:encode_extension).with('bar.crx').and_return('encoded_bar')307308opts = described_class.new(browser_version: '75',309platform_name: 'win10',310accept_insecure_certs: false,311page_load_strategy: :eager,312unhandled_prompt_behavior: :accept_and_notify,313strict_file_interactability: true,314timeouts: {script: 40000,315page_load: 400000,316implicit: 1},317set_window_rect: false,318args: %w[foo bar],319prefs: {foo: 'bar',320key_that_should_not_be_camelcased: 'baz',321nested_one: {nested_two: 'bazbar'}},322binary: '/foo/bar',323extensions: ['foo.crx', 'bar.crx'],324encoded_extensions: ['encoded_foobar'],325emulation: {device_name: :mine},326local_state: {327foo: 'bar',328key_that_should_not_be_camelcased: 'baz'329},330detach: true,331debugger_address: '127.0.0.1:8181',332exclude_switches: %w[foobar barfoo],333minidump_path: 'linux/only',334perf_logging_prefs: {enable_network: true},335window_types: %w[normal devtools],336android_package: 'package',337android_activity: 'activity',338android_device_serial: '123',339android_use_running_app: true,340'custom:options': {foo: 'bar'})341342key = 'goog:chromeOptions'343expect(opts.as_json).to eq('browserName' => 'chrome',344'browserVersion' => '75',345'platformName' => 'win10',346'acceptInsecureCerts' => false,347'pageLoadStrategy' => 'eager',348'unhandledPromptBehavior' => 'accept and notify',349'strictFileInteractability' => true,350'timeouts' => {'script' => 40000,351'pageLoad' => 400000,352'implicit' => 1},353'setWindowRect' => false,354'custom:options' => {'foo' => 'bar'},355key => {'args' => %w[foo bar],356'prefs' => {'foo' => 'bar',357'key_that_should_not_be_camelcased' => 'baz',358'nested_one' => {'nested_two' => 'bazbar'}},359'binary' => '/foo/bar',360'extensions' => %w[encoded_foobar encoded_foo encoded_bar],361'mobileEmulation' => {'deviceName' => 'mine'},362'localState' => {363'foo' => 'bar',364'key_that_should_not_be_camelcased' => 'baz'365},366'detach' => true,367'debuggerAddress' => '127.0.0.1:8181',368'excludeSwitches' => %w[foobar barfoo],369'minidumpPath' => 'linux/only',370'perfLoggingPrefs' => {'enableNetwork' => true},371'windowTypes' => %w[normal devtools],372'androidPackage' => 'package',373'androidActivity' => 'activity',374'androidDeviceSerial' => '123',375'androidUseRunningApp' => true})376end377end378end379end # Chrome380end # WebDriver381end # Selenium382383384