-
Notifications
You must be signed in to change notification settings - Fork 504
/
__init__.py
546 lines (416 loc) · 19.4 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
# -*- coding: utf-8 -*-:
# Copyright 2012 splinter authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
"""
This module contains the basic API for splinter drivers and elemnts.
"""
from splinter.within import Within
from splinter.meta import InheritedDocs
from splinter.request_handler.request_handler import RequestHandler
class DriverAPI(RequestHandler):
"""
Basic driver API class.
"""
__metaclass__ = InheritedDocs
driver_name = None
@property
def title(self):
"""
Title of current page.
"""
raise NotImplementedError("%s doesn't support access to the title." % self.driver_name)
def __enter__(self):
"""
Context manager to use the browser safely.
"""
raise NotImplementedError("%s doesn't support use by 'with' statement." % self.driver_name)
def __exit__(self):
"""
Context manager to use the browser safely.
"""
raise NotImplementedError("%s doesn't support use by 'with' statement." % self.driver_name)
@property
def html(self):
"""
Source of current page.
"""
raise NotImplementedError("%s doesn't support access to the html." % self.driver_name)
@property
def url(self):
"""
URL of current page.
"""
raise NotImplementedError("%s doesn't support access to the url." % self.driver_name)
def visit(self, url):
"""
Visits a given URL.
The ``url`` parameter is a string.
"""
raise NotImplementedError("%s doesn't visit any url." % self.driver_name)
def back(self):
"""
Back to the last URL in the browsing history.
If there is no URL to back, this method does nothing.
"""
raise NotImplementedError("%s doesn't support moving back in history." % self.driver_name)
def forward(self):
"""
Forward to the next URL in the browsing history.
If there is no URL to forward, this method does nothing.
"""
raise NotImplementedError("%s doesn't support moving forward in history." % self.driver_name)
def reload(self):
"""
Revisits the current URL
"""
raise NotImplementedError("%s doesn't support reloading the page." % self.driver_name)
def get_alert(self):
"""
Changes the context for working with alerts and prompts.
For more details, check the :doc:`docs about iframes, alerts and prompts </iframes-and-alerts>`
"""
raise NotImplementedError("%s doesn't support alerts." % self.driver_name)
def get_iframe(self, name):
"""
Changes the context for working with iframes.
For more details, check the :doc:`docs about iframes, alerts and prompts </iframes-and-alerts>`
"""
raise NotImplementedError("%s doesn't support frames." % self.driver_name)
def execute_script(self, script):
"""
Executes a given JavaScript in the browser.
e.g.: ::
>>> browser.execute_script('document.getElementById("body").innerHTML = "<p>Hello world!</p>"')
"""
raise NotImplementedError("%s doesn't support executiong of arbitrary JavaScript." % self.driver_name)
def evaluate_script(self, script):
"""
Similar to :meth:`execute_script <DriverAPI.execute_script>` method.
Executes javascript in the browser and returns the value of the expression.
e.g.: ::
>>> assert 4 == browser.evaluate_script('2 + 2')
"""
raise NotImplementedError("%s doesn't support evaluation of arbitrary JavaScript." % self.driver_name)
def find_by_css(self, css_selector):
"""
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`, using a CSS selector to query the
current page content.
"""
raise NotImplementedError("%s doesn't support finding elements by css selector." % self.driver_name)
def find_by_xpath(self, xpath):
"""
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`, using a xpath selector to query the
current page content.
"""
raise NotImplementedError("%s doesn't support finding elements by xpath selector." % self.driver_name)
def find_by_name(self, name):
"""
Finds elements in current page by them name.
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`.
"""
raise NotImplementedError("%s doesn't support finding elements by name." % self.driver_name)
def find_by_id(self, id):
"""
Finds an element in current page by its id.
Even when only one element is find, this method returns an instance of :class:`ElementList <splinter.element_list.ElementList>`
"""
raise NotImplementedError("%s doesn't support finding elements by id." % self.driver_name)
def find_by_value(self, value):
"""
Finds elements in current page by them value.
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`
"""
raise NotImplementedError("%s doesn't support finding elements by value." % self.driver_name)
def find_by_tag(self, tag):
"""
Find all elements of a given tag in current page.
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`
"""
raise NotImplementedError("%s doesn't support finding elements by tag." % self.driver_name)
def find_link_by_href(self, href):
"""
Find all elements of a given tag in current page.
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`
"""
raise NotImplementedError("%s doesn't support finding links by href." % self.driver_name)
def find_link_by_partial_href(self, partial_href):
"""
Find links by looking for a partial ``str`` in them href attribute.
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`
"""
raise NotImplementedError("%s doesn't support finding links by partial href." % self.driver_name)
def find_link_by_text(self, text):
"""
Find links querying for they text.
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`
"""
raise NotImplementedError("%s doesn't support finding links by text." % self.driver_name)
def find_link_by_partial_text(self, partial_text):
"""
Find links by looking for a partial ``str`` in them text.
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`
"""
raise NotImplementedError("%s doesn't support finding links by partial text." % self.driver_name)
def find_option_by_value(self, value):
"""
Finds ``<option>`` elements by them value.
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`
"""
raise NotImplementedError("%s doesn't support finding options by value." % self.driver_name)
def find_option_by_text(self, text):
"""
Finds ``<option>`` elements by them text.
Returns an instance of :class:`ElementList <splinter.element_list.ElementList>`
"""
raise NotImplementedError("%s doesn't support finding options by text." % self.driver_name)
def is_text_present(self, text, wait_time=None):
"""
Searchs for ``text`` in the browser and wait the seconds specified in ``wait_time``.
Returns True if finds a match for the ``text`` and False if not.
"""
raise NotImplementedError("%s doesn't support checking if some text is present in the html. " % self.driver_name)
def type(self, name, value, slowly=False):
"""
Types the ``value`` in the field identified by ``name``.
It's useful to test javascript events like keyPress, keyUp, keyDown, etc.
"""
raise NotImplementedError("%s doesn't support typing on fields by name." % self.driver_name)
def fill(self, name, value):
"""
Fill the field identified by ``name`` with the content specified by ``value``.
"""
raise NotImplementedError("%s doesn't support filling fields by name." % self.driver_name)
def fill_form(self, field_values):
"""
Fill the fields identified by ``name`` with the content specified by ``value`` in a dict.
"""
raise NotImplementedError("%s doesn't support filling forms with a dict." % self.driver_name)
def choose(self, name, value):
"""
Chooses a value in a radio buttons group.
Suppose you have the two radio buttons in a page, with the name ``gender`` and values 'F' and 'M'.
If you use the ``choose`` method the following way:
>>> browser.choose('gender', 'F')
Then you're choosing the female gender.
"""
raise NotImplementedError("%s doesn't support choosing options." % self.driver_name)
def check(self, name):
"""
Checks a checkbox by its name.
Example:
>>> browser.check("agree-with-terms")
If you call ``browser.check`` n times, the checkbox keeps checked, it never get unchecked.
To unckech a checkbox, take a look in the :meth:`uncheck <DriverAPI.uncheck>` method.
"""
raise NotImplementedError("%s doesn't support checking elements." % self.driver_name)
def uncheck(self, name):
"""
Unchecks a checkbox by its name.
Example:
>>> browser.uncheck("send-me-emails")
If you call ``brower.uncheck`` n times, the checkbox keeps unchecked, it never get checked.
To check a checkbox, take a look in the :meth:`check <DriverAPI.check>` method.
"""
raise NotImplementedError("%s doesn't support unchecking elements." % self.driver_name)
def select(self, name, value):
"""
Selects an ``<option>`` element in an ``<select>`` element using the ``name`` of the ``<select>`` and
the ``value`` of the ``<option>``.
Example:
>>> browser.select("state", "NY")
"""
raise NotImplementedError("%s doesn't support selecting options in 'select' element." % self.driver_name)
def click_link_by_href(self, href):
"""
Clicks in a link by its ``href`` attribute.
"""
return self.find_link_by_href(href).first.click()
def click_link_by_partial_href(self, partial_href):
"""
Clicks in a link by looking for partial content of ``href`` attribute.
"""
return self.find_link_by_partial_href(partial_href).first.click()
def click_link_by_text(self, text):
"""
Clicks in a link by its ``text``.
"""
return self.find_link_by_text(text).first.click()
def click_link_by_partial_text(self, partial_text):
"""
Clicks in a link by partial content of its text.
"""
return self.find_link_by_partial_text(partial_text).first.click()
def within(self, context):
return Within(self.find_by_css(context))
def quit(self):
"""
Quits the browser, closing its windows (if it has one).
After quit the browser, you can't use it anymore.
"""
raise NotImplementedError("%s doesn't support quit" % self.driver_name)
def is_element_present_by_css(self, css_selector, wait_time=None):
"""
Verify if the element is present in the current page by css, and wait the specified time in ``wait_time``.
Returns True if the element is present and False if is not present.
"""
raise NotImplementedError("%s doesn't support verifying if element is present by css" % self.driver_name)
def is_element_not_present_by_css(self, css_selector, wait_time=None):
"""
Verify if the element is not present in the current page by css, and wait the specified time in ``wait_time``.
Returns True if the element is not present and False if is present.
"""
raise NotImplementedError("%s doesn't support verifying if element is not present by css" % self.driver_name)
def is_element_present_by_xpath(self, xpath, wait_time=None):
"""
Verify if the element is present in the current page by xpath, and wait the specified time in ``wait_time``.
Returns True if the element is present and False if is not present.
"""
raise NotImplementedError("%s doesn't support verifying if element is present by xpath" % self.driver_name)
def is_element_not_present_by_xpath(self, xpath, wait_time=None):
"""
Verify if the element is not present in the current page by xpath, and wait the specified time in ``wait_time``.
Returns True if the element is not present and False if is present.
"""
raise NotImplementedError("%s doesn't support verifying if element is not present by xpath" % self.driver_name)
def is_element_present_by_tag(self, tag, wait_time=None):
"""
Verify if the element is present in the current page by tag, and wait the specified time in ``wait_time``.
Returns True if the element is present and False if is not present.
"""
raise NotImplementedError("%s doesn't support verifying if element is present by tag" % self.driver_name)
def is_element_not_present_by_tag(self, tag, wait_time=None):
"""
Verify if the element is not present in the current page by tag, and wait the specified time in ``wait_time``.
Returns True if the element is not present and False if is present.
"""
raise NotImplementedError("%s doesn't support verifying if element is not present by tag" % self.driver_name)
def is_element_present_by_name(self, name, wait_time=None):
"""
Verify if the element is present in the current page by name, and wait the specified time in ``wait_time``.
Returns True if the element is present and False if is not present.
"""
raise NotImplementedError("%s doesn't support verifying if element is present by name" % self.driver_name)
def is_element_not_present_by_name(self, name, wait_time=None):
"""
Verify if the element is not present in the current page by name, and wait the specified time in ``wait_time``.
Returns True if the element is not present and False if is present.
"""
raise NotImplementedError("%s doesn't support verifying if element is not present by name" % self.driver_name)
def is_element_present_by_value(self, value, wait_time=None):
"""
Verify if the element is present in the current page by value, and wait the specified time in ``wait_time``.
Returns True if the element is present and False if is not present.
"""
raise NotImplementedError("%s doesn't support verifying if element is present by value" % self.driver_name)
def is_element_not_present_by_value(self, value, wait_time=None):
"""
Verify if the element is not present in the current page by value, and wait the specified time in ``wait_time``.
Returns True if the element is not present and False if is present.
"""
raise NotImplementedError("%s doesn't support verifying if element is not present by value" % self.driver_name)
def is_element_present_by_id(self, id, wait_time=None):
"""
Verify if the element is present in the current page by id, and wait the specified time in ``wait_time``.
Returns True if the element is present and False if is not present.
"""
raise NotImplementedError("%s doesn't support verifying if element is present by id" % self.driver_name)
def is_element_not_present_by_id(self, id, wait_time=None):
"""
Verify if the element is present in the current page by id, and wait the specified time in ``wait_time``.
Returns True if the element is not present and False if is present.
"""
raise NotImplementedError("%s doesn't support verifying if element is not present by id" % self.driver_name)
@property
def cookies(self):
"""
A :class:`CookieManager <splinter.cookie_manager.CookieManagerAPI>` instance.
For more details, check the :doc:`cookies manipulation section </cookies>`.
"""
raise NotImplementedError("%s doesn't support cookies manipulation" % self.driver_name)
class ElementAPI(object):
"""
Basic element API class.
Any element in the page can be represented as an instance of ``ElementAPI``.
Once you have an instance, you can easily access attributes like a ``dict``:
>>> element = browser.find_by_id("link-logo").first
>>> assert element['href'] == 'http://splinter.cobrateam.info'
You can also interact with the instance using the methods and properties listed below.
"""
__metaclass__ = InheritedDocs
def _get_value(self):
raise NotImplementedError
def _set_value(self, value):
raise NotImplementedError
#: Value of the element, usually a form element
value = property(_get_value, _set_value)
@property
def text(self):
"""
String of all of the text within the element. HTML tags are stripped.
"""
raise NotImplementedError
def click(self):
"""
Clicks in the element.
"""
raise NotImplementedError
def check(self):
"""
Checks the element, if it's "checkable" (e.g.: a checkbox).
If the element is already checked, this method does nothing. For unchecking
elements, take a loot in the :meth:`uncheck <ElementAPI.uncheck>` method.
"""
raise NotImplementedError
def uncheck(self):
"""
Unchecks the element, if it's "checkable" (e.g.: a checkbox).
If the element is already unchecked, this method does nothing. For checking
elements, take a loot in the :meth:`check <ElementAPI.check>` method.
"""
raise NotImplementedError
@property
def checked(self):
"""
Boolean property that says if the element is checked or not.
Example:
>>> element.check()
>>> assert element.checked
>>> element.uncheck()
>>> assert not element.checked
"""
raise NotImplementedError
@property
def visible(self):
"""
Boolean property that says if the element is visible or hidden in the current page.
"""
raise NotImplementedError
def has_class(self, class_name):
"""
Indicates whether the element has the given class.
"""
raise NotImplementedError
def mouse_over(self):
"""
Puts the mouse over the element.
"""
raise NotImplementedError
def mouse_out(self):
"""
Moves the mouse away from the element.
"""
raise NotImplementedError
def fill(self, value):
"""
Fill the field with the content specified by ``value``.
"""
raise NotImplementedError
def type(self, value, slowly=False):
"""
Types the ``value`` in the field.
It's useful to test javascript events like keyPress, keyUp, keyDown, etc.
"""
raise NotImplementedError
def __getitem__(self, attribute):
raise NotImplementedError