Skip to content

Commit 44a41f0

Browse files
authored
Adding support for plugin class doc (robotframework#1433)
* Adding support for plugin class doc Fixes robotframework#1430
1 parent 109caa2 commit 44a41f0

11 files changed

+1708
-37
lines changed

src/SeleniumLibrary/__init__.py

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
16-
16+
import re
1717
from collections import namedtuple
18-
from inspect import isclass
18+
from inspect import getdoc, isclass
1919

2020
from robot.api import logger
2121
from robot.errors import DataError
@@ -59,19 +59,7 @@ class SeleniumLibrary(DynamicCore):
5959
[https://github.com/robotframework/SeleniumLibrary#browser-drivers|Browser drivers chapter]
6060
for more details about WebDriver binary installation.
6161
62-
== Table of contents ==
63-
64-
- `Locating elements`
65-
- `Browser and Window`
66-
- `Timeouts, waits and delays`
67-
- `Run-on-failure functionality`
68-
- `Boolean arguments`
69-
- `Plugins`
70-
- `EventFiringWebDriver`
71-
- `Thread support`
72-
- `Importing`
73-
- `Shortcuts`
74-
- `Keywords`
62+
%TOC%
7563
7664
= Locating elements =
7765
@@ -232,14 +220,14 @@ class SeleniumLibrary(DynamicCore):
232220
== Browser ==
233221
234222
When `Open Browser` or `Create WebDriver` keyword is called, it
235-
will create a new Selenium WebDriver instance by using the
223+
will create a new Selenium WebDriver instance by using the
236224
[https://www.seleniumhq.org/docs/03_webdriver.jsp|Selenium WebDriver]
237-
API. In SeleniumLibrary terms, a new broser is created. It is
238-
possible to start multiple independent browsers (Selenium Webdriver
239-
instances) at the same time, by calling `Open Browser` or
240-
`Create WebDriver` multiple times. These browsers are usually
241-
independent to each other and do not share data like cookies,
242-
sessions or profiles. Typicall when browser starts, it
225+
API. In SeleniumLibrary terms, a new broser is created. It is
226+
possible to start multiple independent browsers (Selenium Webdriver
227+
instances) at the same time, by calling `Open Browser` or
228+
`Create WebDriver` multiple times. These browsers are usually
229+
independent to each other and do not share data like cookies,
230+
sessions or profiles. Typicall when browser starts, it
243231
creates a single window in the desktop.
244232
245233
== Window ==
@@ -259,8 +247,8 @@ class SeleniumLibrary(DynamicCore):
259247
| `Execute Javascript` window.open() # Opens a new window with location about:blank
260248
261249
In the example in below opens multiple browser and windows,
262-
to demonstrate how the different keywords can be used to interact
263-
with a browser and windows atteched to the browser.
250+
to demonstrate how the different keywords can be used to interact
251+
with a browser and windows attached to the browser.
264252
265253
Structure:
266254
| BrowserA
@@ -286,13 +274,13 @@ class SeleniumLibrary(DynamicCore):
286274
| @{locations 1} | `Get Locations` | | | # By default lists locations under the currectly active browser. |
287275
| @{locations 2} | `Get Locations` | browser=ALL | | # By using browser=ALL argument keyword list all locations from all browsers. |
288276
289-
The above example, @{locations 1} contains the following items:
290-
https://robotframework.org/, https://robocon.io/ and
277+
The above example, @{locations 1} contains the following items:
278+
https://robotframework.org/, https://robocon.io/ and
291279
https://github.com/robotframework/'. The @{locations 2}
292-
contains the following items: https://robotframework.org/,
280+
contains the following items: https://robotframework.org/,
293281
https://robocon.io/, https://github.com/robotframework/'
294282
and 'https://github.com/.
295-
283+
296284
= Timeouts, waits and delays =
297285
298286
This section discusses different ways how to wait for elements to
@@ -385,15 +373,6 @@ class SeleniumLibrary(DynamicCore):
385373
``false``, ``no`` and ``none``, were considered true. Starting from
386374
SeleniumLibrary 4.0, strings ``0`` and ``off`` are considered as false.
387375
388-
= Plugins =
389-
390-
SeleniumLibrary offers plugins as a way to modify and add library keywords and modify some of the internal
391-
functionality without creating new library or hacking the source code. See
392-
[https://github.com/robotframework/SeleniumLibrary/blob/master/docs/extending/extending.rst#Plugins|plugin API]
393-
documentation for further details.
394-
395-
Plugin API is new SeleniumLibrary 4.0
396-
397376
= EventFiringWebDriver =
398377
399378
The SeleniumLibrary offers support for
@@ -411,6 +390,15 @@ class SeleniumLibrary(DynamicCore):
411390
Selenium tool is not thread safe] within one browser/driver instance.
412391
Because of the limitation in the Selenium side, the keywords or the
413392
API provided by the SeleniumLibrary is not thread safe.
393+
394+
= Plugins =
395+
396+
SeleniumLibrary offers plugins as a way to modify and add library keywords and modify some of the internal
397+
functionality without creating new library or hacking the source code. See
398+
[https://github.com/robotframework/SeleniumLibrary/blob/master/docs/extending/extending.rst#Plugins|plugin API]
399+
documentation for further details.
400+
401+
Plugin API is new SeleniumLibrary 4.0
414402
"""
415403
ROBOT_LIBRARY_SCOPE = 'GLOBAL'
416404
ROBOT_LIBRARY_VERSION = __version__
@@ -465,8 +453,10 @@ def __init__(self, timeout=5.0, implicit_wait=0.0,
465453
self.event_firing_webdriver = None
466454
if is_truthy(event_firing_webdriver):
467455
self.event_firing_webdriver = self._parse_listener(event_firing_webdriver)
456+
self._plugins = []
468457
if is_truthy(plugins):
469458
plugin_libs = self._parse_plugins(plugins)
459+
self._plugins = plugin_libs
470460
libraries = libraries + plugin_libs
471461
self._drivers = WebDriverCache()
472462
DynamicCore.__init__(self, libraries)
@@ -487,6 +477,33 @@ def get_keyword_tags(self, name):
487477
tags.append('plugin')
488478
return tags
489479

480+
def get_keyword_documentation(self, name):
481+
if name == '__intro__':
482+
return self._get_intro_documentation()
483+
return DynamicCore.get_keyword_documentation(self, name)
484+
485+
def _parse_plugin_doc(self):
486+
Doc = namedtuple('Doc', 'doc, name')
487+
for plugin in self._plugins:
488+
yield Doc(doc=getdoc(plugin) or 'No plugin documentation found.',
489+
name=plugin.__class__.__name__)
490+
491+
def _get_intro_documentation(self):
492+
intro = DynamicCore.get_keyword_documentation(self, '__intro__')
493+
for plugin_doc in self._parse_plugin_doc():
494+
intro += '\n\n'
495+
intro = intro + '= Plugin: %s =' % plugin_doc.name + '\n\n'
496+
intro = intro + plugin_doc.doc
497+
return self._create_toc(intro)
498+
499+
def _create_toc(self, intro):
500+
toc = ['== Table of contents ==', '']
501+
all_match = re.findall(r'(^\=\s)(.+)(\s\=$)', intro, re.MULTILINE)
502+
for match in all_match:
503+
toc.append('- `%s`' % match[1])
504+
toc.extend(['- `Importing`', '- `Shortcuts`', '- `Keywords`'])
505+
return intro.replace('%TOC%', '\n'.join(toc))
506+
490507
def register_driver(self, driver, alias):
491508
"""Add's a `driver` to the library WebDriverCache.
492509
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"subdirectory": "approved_files"
3+
}

0 commit comments

Comments
 (0)