1<?php
2
3namespace Facebook\WebDriver;
4
5use Facebook\WebDriver\Exception\IndexOutOfBoundsException;
6use Facebook\WebDriver\Exception\UnsupportedOperationException;
7use Facebook\WebDriver\Remote\DriverCommand;
8use Facebook\WebDriver\Remote\ExecuteMethod;
9
10/**
11 * An abstraction allowing the driver to manipulate the browser's window
12 */
13class WebDriverWindow
14{
15    /**
16     * @var ExecuteMethod
17     */
18    protected $executor;
19    /**
20     * @var bool
21     */
22    protected $isW3cCompliant;
23
24    public function __construct(ExecuteMethod $executor, $isW3cCompliant = false)
25    {
26        $this->executor = $executor;
27        $this->isW3cCompliant = $isW3cCompliant;
28    }
29
30    /**
31     * Get the position of the current window, relative to the upper left corner
32     * of the screen.
33     *
34     * @return WebDriverPoint The current window position.
35     */
36    public function getPosition()
37    {
38        $position = $this->executor->execute(
39            DriverCommand::GET_WINDOW_POSITION,
40            [':windowHandle' => 'current']
41        );
42
43        return new WebDriverPoint(
44            $position['x'],
45            $position['y']
46        );
47    }
48
49    /**
50     * Get the size of the current window. This will return the outer window
51     * dimension, not just the view port.
52     *
53     * @return WebDriverDimension The current window size.
54     */
55    public function getSize()
56    {
57        $size = $this->executor->execute(
58            DriverCommand::GET_WINDOW_SIZE,
59            [':windowHandle' => 'current']
60        );
61
62        return new WebDriverDimension(
63            $size['width'],
64            $size['height']
65        );
66    }
67
68    /**
69     * Minimizes the current window if it is not already minimized.
70     *
71     * @return WebDriverWindow The instance.
72     */
73    public function minimize()
74    {
75        if (!$this->isW3cCompliant) {
76            throw new UnsupportedOperationException('Minimize window is only supported in W3C mode');
77        }
78
79        $this->executor->execute(DriverCommand::MINIMIZE_WINDOW, []);
80
81        return $this;
82    }
83
84    /**
85     * Maximizes the current window if it is not already maximized
86     *
87     * @return WebDriverWindow The instance.
88     */
89    public function maximize()
90    {
91        if ($this->isW3cCompliant) {
92            $this->executor->execute(DriverCommand::MAXIMIZE_WINDOW, []);
93        } else {
94            $this->executor->execute(
95                DriverCommand::MAXIMIZE_WINDOW,
96                [':windowHandle' => 'current']
97            );
98        }
99
100        return $this;
101    }
102
103    /**
104     * Makes the current window full screen.
105     *
106     * @return WebDriverWindow The instance.
107     */
108    public function fullscreen()
109    {
110        if (!$this->isW3cCompliant) {
111            throw new UnsupportedOperationException('The Fullscreen window command is only supported in W3C mode');
112        }
113
114        $this->executor->execute(DriverCommand::FULLSCREEN_WINDOW, []);
115
116        return $this;
117    }
118
119    /**
120     * Set the size of the current window. This will change the outer window
121     * dimension, not just the view port.
122     *
123     * @param WebDriverDimension $size
124     * @return WebDriverWindow The instance.
125     */
126    public function setSize(WebDriverDimension $size)
127    {
128        $params = [
129            'width' => $size->getWidth(),
130            'height' => $size->getHeight(),
131            ':windowHandle' => 'current',
132        ];
133        $this->executor->execute(DriverCommand::SET_WINDOW_SIZE, $params);
134
135        return $this;
136    }
137
138    /**
139     * Set the position of the current window. This is relative to the upper left
140     * corner of the screen.
141     *
142     * @param WebDriverPoint $position
143     * @return WebDriverWindow The instance.
144     */
145    public function setPosition(WebDriverPoint $position)
146    {
147        $params = [
148            'x' => $position->getX(),
149            'y' => $position->getY(),
150            ':windowHandle' => 'current',
151        ];
152        $this->executor->execute(DriverCommand::SET_WINDOW_POSITION, $params);
153
154        return $this;
155    }
156
157    /**
158     * Get the current browser orientation.
159     *
160     * @return string Either LANDSCAPE|PORTRAIT
161     */
162    public function getScreenOrientation()
163    {
164        return $this->executor->execute(DriverCommand::GET_SCREEN_ORIENTATION);
165    }
166
167    /**
168     * Set the browser orientation. The orientation should either
169     * LANDSCAPE|PORTRAIT
170     *
171     * @param string $orientation
172     * @throws IndexOutOfBoundsException
173     * @return WebDriverWindow The instance.
174     */
175    public function setScreenOrientation($orientation)
176    {
177        $orientation = mb_strtoupper($orientation);
178        if (!in_array($orientation, ['PORTRAIT', 'LANDSCAPE'], true)) {
179            throw new IndexOutOfBoundsException(
180                'Orientation must be either PORTRAIT, or LANDSCAPE'
181            );
182        }
183
184        $this->executor->execute(
185            DriverCommand::SET_SCREEN_ORIENTATION,
186            ['orientation' => $orientation]
187        );
188
189        return $this;
190    }
191}
192