Skip to content

Commit 253d188

Browse files
cuff-linksdavehunt
authored andcommitted
Added python context manager for chrome/content in Firefox (#2753)
1 parent 36e67cc commit 253d188

3 files changed

Lines changed: 59 additions & 0 deletions

File tree

py/selenium/webdriver/firefox/remote_connection.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class FirefoxRemoteConnection(RemoteConnection):
2222
def __init__(self, remote_server_addr, keep_alive=True):
2323
RemoteConnection.__init__(self, remote_server_addr, keep_alive)
2424

25+
self._commands["GET_CONTEXT"] = ('GET', '/session/$sessionId/moz/context')
2526
self._commands["SET_CONTEXT"] = ("POST", "/session/$sessionId/moz/context")
2627
self._commands["ELEMENT_GET_ANONYMOUS_CHILDREN"] = \
2728
("POST", "/session/$sessionId/moz/xbl/$id/anonymous_children")

py/selenium/webdriver/firefox/webdriver.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import types
3232

3333
from .extension_connection import ExtensionConnection
34+
from contextlib import contextmanager
35+
3436
from .firefox_binary import FirefoxBinary
3537
from .firefox_profile import FirefoxProfile
3638
from .options import Options
@@ -130,6 +132,10 @@ def __init__(self, firefox_profile=None, firefox_binary=None,
130132

131133
# W3C remote
132134
# TODO(ato): Perform conformance negotiation
135+
136+
self.CONTEXT_CHROME = 'chrome'
137+
self.CONTEXT_CONTENT = 'content'
138+
133139
if capabilities.get("marionette"):
134140
self.service = Service(executable_path, log_path=log_path)
135141
self.service.start()
@@ -195,3 +201,25 @@ def firefox_profile(self):
195201

196202
def set_context(self, context):
197203
self.execute("SET_CONTEXT", {"context": context})
204+
205+
@contextmanager
206+
def context(self, context):
207+
"""Sets the context that Selenium commands are running in using
208+
a `with` statement. The state of the context on the server is
209+
saved before entering the block, and restored upon exiting it.
210+
211+
:param context: Context, may be one of the class properties
212+
`CONTEXT_CHROME` or `CONTEXT_CONTENT`.
213+
214+
Usage example::
215+
216+
with selenium.context(selenium.CONTEXT_CHROME):
217+
# chrome scope
218+
... do stuff ...
219+
"""
220+
initial_context = self.execute('GET_CONTEXT').pop('value')
221+
self.set_context(context)
222+
try:
223+
yield
224+
finally:
225+
self.set_context(initial_context)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Licensed to the Software Freedom Conservancy (SFC) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The SFC licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
19+
class TestUsingContext(object):
20+
21+
def test_context_sets_correct_context_and_returns(self, driver):
22+
23+
def get_context():
24+
return driver.execute('GET_CONTEXT').pop('value')
25+
26+
assert get_context() == driver.CONTEXT_CONTENT
27+
with driver.context(driver.CONTEXT_CHROME):
28+
assert get_context() == driver.CONTEXT_CHROME
29+
assert get_context() == driver.CONTEXT_CONTENT
30+

0 commit comments

Comments
 (0)