1<?php
2
3namespace Facebook\WebDriver\Firefox;
4
5use ReturnTypeWillChange;
6
7/**
8 * Class to manage Firefox-specific capabilities
9 *
10 * @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions
11 */
12class FirefoxOptions implements \JsonSerializable
13{
14    /** @var string The key of FirefoxOptions in desired capabilities */
15    const CAPABILITY = 'moz:firefoxOptions';
16    /** @var string */
17    const OPTION_ARGS = 'args';
18    /** @var string */
19    const OPTION_PREFS = 'prefs';
20
21    /** @var array */
22    private $options = [];
23    /** @var array */
24    private $arguments = [];
25    /** @var array */
26    private $preferences = [];
27
28    public function __construct()
29    {
30        // Set default preferences:
31        // disable the "Reader View" help tooltip, which can hide elements in the window.document
32        $this->setPreference(FirefoxPreferences::READER_PARSE_ON_LOAD_ENABLED, false);
33        // disable JSON viewer and let JSON be rendered as raw data
34        $this->setPreference(FirefoxPreferences::DEVTOOLS_JSONVIEW, false);
35    }
36
37    /**
38     * Directly set firefoxOptions.
39     * Use `addArguments` to add command line arguments and `setPreference` to set Firefox about:config entry.
40     *
41     * @param string $name
42     * @param mixed $value
43     * @return self
44     */
45    public function setOption($name, $value)
46    {
47        if ($name === self::OPTION_PREFS) {
48            throw new \InvalidArgumentException('Use setPreference() method to set Firefox preferences');
49        }
50        if ($name === self::OPTION_ARGS) {
51            throw new \InvalidArgumentException('Use addArguments() method to add Firefox arguments');
52        }
53
54        $this->options[$name] = $value;
55
56        return $this;
57    }
58
59    /**
60     * Command line arguments to pass to the Firefox binary.
61     * These must include the leading dash (-) where required, e.g. ['-headless'].
62     *
63     * @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions#args
64     * @param string[] $arguments
65     * @return self
66     */
67    public function addArguments(array $arguments)
68    {
69        $this->arguments = array_merge($this->arguments, $arguments);
70
71        return $this;
72    }
73
74    /**
75     * Set Firefox preference (about:config entry).
76     *
77     * @see http://kb.mozillazine.org/About:config_entries
78     * @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions#prefs
79     * @param string $name
80     * @param string|bool|int $value
81     * @return self
82     */
83    public function setPreference($name, $value)
84    {
85        $this->preferences[$name] = $value;
86
87        return $this;
88    }
89
90    /**
91     * @return array
92     */
93    public function toArray()
94    {
95        $array = $this->options;
96        if (!empty($this->arguments)) {
97            $array[self::OPTION_ARGS] = $this->arguments;
98        }
99        if (!empty($this->preferences)) {
100            $array[self::OPTION_PREFS] = $this->preferences;
101        }
102
103        return $array;
104    }
105
106    #[ReturnTypeWillChange]
107    public function jsonSerialize()
108    {
109        return new \ArrayObject($this->toArray());
110    }
111}
112