Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use "All" page of requested entity as starting url for session #422

Merged
merged 4 commits into from
Nov 18, 2019

Conversation

mirekdlugosz
Copy link
Contributor

This is Airgun-only re-implementation of idea presented by @omkarkhatavkar in SatelliteQE/robottelo#7442

The main goal here is to use entity "All items" URL as starting point for session. This way list of all entities will be visible right after logging in (instead of displaying dashboard, which we hardly ever need).

This is implemented by deferring execution of browser initialization code until entity is requested. It has two effects:

  1. We can let each entity define URL fragment on their own. Web-specific data is kept within Airgun, which is in line of our design principles. As a result, this change is completely transparent to Robottelo - no test must be changed to benefit from this PR.
  2. If you happen to use Session context manager, but never actually interact with it, browser will not be initialized. This will save time during test development and allows us to put more code inside session context (as there is no performance penalty for that).

Test case:

$ pytest -s --durations=0 --count 3 -k end_to_end tests/foreman/ui/test_lifecycleenvironment.py

Before change:

=================================================================================== slowest test durations ====================================================================================
73.52s call     tests/foreman/ui/test_lifecycleenvironment.py::test_positive_end_to_end[1-3]
71.91s call     tests/foreman/ui/test_lifecycleenvironment.py::test_positive_end_to_end[2-3]
70.26s call     tests/foreman/ui/test_lifecycleenvironment.py::test_positive_end_to_end[3-3]
6.75s setup    tests/foreman/ui/test_lifecycleenvironment.py::test_positive_end_to_end[1-3]
0.24s teardown tests/foreman/ui/test_lifecycleenvironment.py::test_positive_end_to_end[3-3]

After change:

=================================================================================== slowest test durations ====================================================================================
61.88s call     tests/foreman/ui/test_lifecycleenvironment.py::test_positive_end_to_end[3-3]
61.47s call     tests/foreman/ui/test_lifecycleenvironment.py::test_positive_end_to_end[1-3]
60.53s call     tests/foreman/ui/test_lifecycleenvironment.py::test_positive_end_to_end[2-3]
4.36s setup    tests/foreman/ui/test_lifecycleenvironment.py::test_positive_end_to_end[1-3]
0.26s teardown tests/foreman/ui/test_lifecycleenvironment.py::test_positive_end_to_end[3-3]

So, with that PR, we can expect individual test execution time to be reduced by 8 to 13 seconds.

I am also running entire UI Robottelo suite, but this takes forever.

Reduces individual test run time by 8-13 seconds
rochacbruno
rochacbruno previously approved these changes Nov 14, 2019
Copy link

@rochacbruno rochacbruno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Comment is only a suggestion.


@cached_property
def virtwho_configure(self):
"""Instance of Virtwho Configure entity."""
return VirtwhoConfigureEntity(self.browser)
return self._open(VirtwhoConfigureEntity)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is not a blocker, the PR LGTM.

I only have one comment/suggestion about how it is possible to make it DRY, all that @cached_property are similiar and too much code repetition.

@lru_cache  # lru_cache can replace @cached_property
def get_open_entity(self, name):
    # This dict can actually be automatically built from `airgun.entities` members.
    entities = {
        'virtwho_configure': VirtwhoConfigureEntity,
       'usergroup': UserGroupEntity,
      ...
    }
    return self._open(entities[name])

def __getattr__(self, name):
    """Called when an attribute lookup has not found"""
    try:
        return self.get_open_entity(name)
    except KeyError:
        return super().__getattr__(name)

That is just an idea to be tested/evaluated and maybe implemented in another PR because with this it is possible to replace all the repetition, 248 lines becomes 72 lines. (or less)

Any time a session.foo is called, the foo is going to be looked up in the entity list before it raises AttributeError if not found.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rochacbruno looks like to be a good idea not sure here about consequences, unrelated to this PR. can you please create an issue in Airgun with mentioning details.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this change, both idioms below are supported:
    with session:
        # do something
    with session(url='url'):
        # open $HOSTNAME/url and do something

Initially, we wanted tests to only submit new URL path, but since it's
easy to extend that to other arguments, why not do that?

Also, actually don't open browser if session.entity is never invoked in
test.
@mirekdlugosz
Copy link
Contributor Author

mirekdlugosz commented Nov 18, 2019

With bd1653b, both of following idioms are supported:

with session:
   # do something - starting URL will be read from requested entity
with session(url="url"):
   # do something - starting URL will be $HOSTNAME/url, i.e. provided by test and not entity

We initially discussed session('url') format, but I decided to generalize this to other arguments supported by __init__. So you can also use it to login as specific user (session(user_name, user_pass)), or pass session cookie obtained in test (session(session_cookie=cookie))).

I am very much interested on what you think about this API.

@omkarkhatavkar
Copy link

@mirekdlugosz overall looks nice, we are adding many ways access session makes more sense to me. I have one doubt here If we use plain with session: it will still navigate entity directly instead navigating from the menubar. For this, we can have the first test from each entity to be using plain session.

In other cases with with session('entity/create') will navigate to any required page.

@mirekdlugosz
Copy link
Contributor Author

I have one doubt here If we use plain with session: it will still navigate entity directly instead navigating from the menubar.

With plain with session:, it will be:

All page for entity --(use button)-> New entity page

I have checked on test_positive_create_with_cv from tests/foreman/ui/test_activationkey.py:

# with session:
$ pytest -v tests/foreman/ui/test_activationkey.py -k 'test_positive_create_with_cv[1]'
==================================================================== 1 passed, 42 deselected, 1 warnings in 97.66 seconds =====================================================================
# with session(url='/activation_keys/new')
$ pytest -v tests/foreman/ui/test_activationkey.py -k 'test_positive_create_with_cv[1]'
==================================================================== 1 passed, 42 deselected, 1 warnings in 95.05 seconds =====================================================================

Of course these are only single runs for each.

So yes, it will reduce execution time a little further if we change robottelo to set initial URL to that of "new entity" page. But that's for another PR, as it must be done in robottelo and not airgun.

@omkarkhatavkar
Copy link

So yes, it will reduce execution time a little further if we change robottelo to set initial URL to that of "new entity" page. But that's for another PR, as it must be done in robottelo and not airgun.

Absolutely, thanks for examples

omkarkhatavkar
omkarkhatavkar previously approved these changes Nov 18, 2019
Copy link

@omkarkhatavkar omkarkhatavkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

rochacbruno
rochacbruno previously approved these changes Nov 18, 2019
Copy link

@rochacbruno rochacbruno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

with a question comment for @mirekdlugosz

Copy link

@rochacbruno rochacbruno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link

@omkarkhatavkar omkarkhatavkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants