|
| 1 | +# coding: utf-8 |
| 2 | +""" |
| 3 | +This module contains commands to interact with UI via console |
| 4 | +
|
| 5 | +Commands included: |
| 6 | +
|
| 7 | +Browse |
| 8 | +------ |
| 9 | +
|
| 10 | +A command to open a browser session using the configured preferences from |
| 11 | +`robottelo.properties` file and provide an interactive shell to play with |
| 12 | +browser session:: |
| 13 | +
|
| 14 | + $ manage ui browse <entity> |
| 15 | + >>> session.nav.go_to_entity() |
| 16 | + >>> session.ui.make_user(username='my_username') |
| 17 | +
|
| 18 | +Please take a look at :doc:`commands package </features/commands>` page |
| 19 | +in documentation for more details. |
| 20 | +
|
| 21 | +""" |
| 22 | +import click |
| 23 | +import import_string |
| 24 | + |
| 25 | +from functools import partial |
| 26 | +from inspect import getmembers |
| 27 | +from manage.cli import create_shell |
| 28 | +from nailgun import entities |
| 29 | +from robottelo.config import settings |
| 30 | +from robottelo.constants import UI_CRUD |
| 31 | +from robottelo.helpers import Storage |
| 32 | +from robottelo.ui.browser import browser as selenium_browser |
| 33 | +from robottelo.ui.browser import DockerBrowser |
| 34 | +from robottelo.ui import factory as ui_factory |
| 35 | +from robottelo.ui.session import Session |
| 36 | + |
| 37 | + |
| 38 | +def _get_browser(browser=None): |
| 39 | + """Gets a new instance of a browser to interact""" |
| 40 | + |
| 41 | + browser = browser or settings.browser |
| 42 | + if browser == 'docker': |
| 43 | + _docker_browser = DockerBrowser() |
| 44 | + _docker_browser.start() |
| 45 | + _browser = _docker_browser.webdriver |
| 46 | + elif browser == "selenium": |
| 47 | + _browser = selenium_browser() |
| 48 | + else: |
| 49 | + raise NotImplementedError( |
| 50 | + "this shell only supports docker and selenium") |
| 51 | + |
| 52 | + _browser.maximize_window() |
| 53 | + _browser.get(settings.server.get_url()) |
| 54 | + return _browser |
| 55 | + |
| 56 | + |
| 57 | +def _import_ui_crud(): |
| 58 | + """Imports all UI crud related classes to shell scope""" |
| 59 | + # FIXME: get all subclasses of robotello.ui.base.Base automatically |
| 60 | + base_module = "robottelo.ui.{0}" |
| 61 | + return { |
| 62 | + name.split('.')[-1]: import_string(base_module.format(name)) |
| 63 | + for name in UI_CRUD |
| 64 | + } |
| 65 | + |
| 66 | + |
| 67 | +@click.command() |
| 68 | +@click.option('--host', required=False, default=None, |
| 69 | + help="satellite host name e.g:'foo.bar.com'") |
| 70 | +@click.option('--browser', required=False, default=None, |
| 71 | + help='selenium or docker (defaults to properties file)') |
| 72 | +@click.argument('entity', required=False, default=None) |
| 73 | +def browse(entity, browser, host): |
| 74 | + """Opens a page in defined browser for interaction:\n |
| 75 | + All parameters defaults to what is in robottelo.properties file.\n |
| 76 | + example: $ manage ui browse activationkey\n |
| 77 | + Opens a browser in ActivationKey scope and gives you |
| 78 | + interactive shell to play with the page\n |
| 79 | + """ |
| 80 | + settings.configure() |
| 81 | + if host: |
| 82 | + settings.server.hostname = host |
| 83 | + current_browser = _get_browser(browser) |
| 84 | + with Session(current_browser) as session: # noqa |
| 85 | + |
| 86 | + ui_crud = _import_ui_crud() |
| 87 | + # Make all UI CRUD entities available in a dict |
| 88 | + # each entity initialized with current_browser instance |
| 89 | + ui_entities = { |
| 90 | + name.lower(): crud_class(current_browser) |
| 91 | + for name, crud_class in ui_crud.items() |
| 92 | + } |
| 93 | + if entity: |
| 94 | + # if entity name specified navigate to the page |
| 95 | + # example: manage ui browse user |
| 96 | + ui_entities[entity.lower()].navigate_to_entity() |
| 97 | + |
| 98 | + # gets all functions from ui.factory module which starts with 'make_' |
| 99 | + ui_factory_members = getmembers( |
| 100 | + ui_factory, |
| 101 | + lambda i: callable(i) and i.__name__.startswith('make') |
| 102 | + ) |
| 103 | + # Usually we need to pass the `session` as 1st argument |
| 104 | + # e.g `make_user(session, username='...')` |
| 105 | + # using `partial` we make session the default 1st argument |
| 106 | + # it allows the use as: `make_user(username='...') |
| 107 | + # and `session` is implicit there. |
| 108 | + ui_factory_functions = { |
| 109 | + name: partial(function, session=session) |
| 110 | + for name, function in ui_factory_members |
| 111 | + } |
| 112 | + |
| 113 | + # now we "inject" the factories and entities under `session.ui` |
| 114 | + session.ui = Storage(ui_entities, ui_factory_functions) |
| 115 | + |
| 116 | + # The same for nailgun.entities.* under `session.api` |
| 117 | + session.api = Storage(dict(getmembers(entities))) |
| 118 | + |
| 119 | + def close(): |
| 120 | + """Hook to close the session and browser atexit it also flushes |
| 121 | + the session history content to the specified file |
| 122 | + """ |
| 123 | + session.close() |
| 124 | + # FIXME: if --out=/path/to/file should save session history |
| 125 | + # see ipython.readthedocs.io/en/stable/config/options/terminal.html |
| 126 | + |
| 127 | + extra_vars = { |
| 128 | + 'session': session, |
| 129 | + 'browser': current_browser, |
| 130 | + 'current_browser': current_browser, |
| 131 | + 'host': settings.server.hostname, |
| 132 | + 'api_factory': entities, |
| 133 | + 'ui_factory': ui_factory |
| 134 | + } |
| 135 | + |
| 136 | + create_shell('ipython', extra_vars=extra_vars, exit_hooks=[close]) |
0 commit comments