Change Owner/Org/Loc entities/views coverage - #1933
Merged
vsedmik merged 2 commits intoJul 24, 2025
Merged
Conversation
Contributor
Reviewer's GuideThis PR refactors multi-host workflows by extracting a shared navigation and selection helper, and adds full coverage for changing owners, organizations, and locations of multiple hosts through new entity methods, UI modals, and view components. Sequence diagram for changing owner of multiple hostssequenceDiagram
actor User
participant AllHostsEntity
participant AllHostsTableView
participant ChangeHostsOwnerModal
User->>AllHostsEntity: change_hosts_owner(host_names, new_owner_name, select_all_hosts)
AllHostsEntity->>AllHostsTableView: all_hosts_navigate_and_select_hosts_helper(...)
AllHostsEntity->>AllHostsTableView: bulk_actions_kebab.click()
AllHostsEntity->>AllHostsTableView: bulk_actions_menu.item_select('Change owner')
AllHostsEntity->>ChangeHostsOwnerModal: instantiate modal
AllHostsEntity->>ChangeHostsOwnerModal: owner_select.item_select(new_owner_name)
AllHostsEntity->>ChangeHostsOwnerModal: confirm_btn.click()
Sequence diagram for changing organization of multiple hostssequenceDiagram
actor User
participant AllHostsEntity
participant AllHostsTableView
participant ChangeOrganizationModal
User->>AllHostsEntity: change_associations_organization(host_names, new_organization, select_all_hosts, option)
AllHostsEntity->>AllHostsTableView: all_hosts_navigate_and_select_hosts_helper(...)
AllHostsEntity->>AllHostsTableView: bulk_actions_kebab.click()
AllHostsEntity->>AllHostsTableView: bulk_actions_menu.item_element('Change associations')
AllHostsEntity->>AllHostsTableView: bulk_actions_change_associations_menu.item_select('Organization')
AllHostsEntity->>ChangeOrganizationModal: instantiate modal
AllHostsEntity->>ChangeOrganizationModal: organization_menu.item_select(new_organization)
AllHostsEntity->>ChangeOrganizationModal: organization_fix_on_mismatch.fill(True) or organization_fail_on_mismatch.fill(True)
AllHostsEntity->>ChangeOrganizationModal: save_button.click()
Sequence diagram for changing location of multiple hostssequenceDiagram
actor User
participant AllHostsEntity
participant AllHostsTableView
participant ChangeLocationModal
User->>AllHostsEntity: change_associations_location(host_names, new_location, select_all_hosts, option)
AllHostsEntity->>AllHostsTableView: all_hosts_navigate_and_select_hosts_helper(...)
AllHostsEntity->>AllHostsTableView: bulk_actions_kebab.click()
AllHostsEntity->>AllHostsTableView: bulk_actions_menu.item_element('Change associations')
AllHostsEntity->>AllHostsTableView: bulk_actions_change_associations_menu.item_select('Location')
AllHostsEntity->>ChangeLocationModal: instantiate modal
AllHostsEntity->>ChangeLocationModal: location_menu.item_select(new_location)
AllHostsEntity->>ChangeLocationModal: location_fix_on_mismatch.fill(True) or location_fail_on_mismatch.fill(True)
AllHostsEntity->>ChangeLocationModal: save_button.click()
Class diagram for new and updated AllHosts entity methods and modalsclassDiagram
class AllHostsEntity {
+delete(host_name)
+bulk_delete_all()
+build_management(reboot, rebuild)
+change_hostgroup(name)
+manage_packages(...)
+manage_errata(...)
+manage_repository_sets(...)
+disassociate_hosts(host_names, select_all_hosts)
+all_hosts_navigate_and_select_hosts_helper(host_names, select_all_hosts)
+change_hosts_owner(host_names, new_owner_name, select_all_hosts)
+change_associations_organization(host_names, new_organization, select_all_hosts, option)
+change_associations_location(host_names, new_location, select_all_hosts, option)
}
class AllHostsTableView {
+bulk_actions_kebab
+bulk_actions_menu
+bulk_actions_change_associations_menu
}
class ChangeHostsOwnerModal {
+owner_select
+confirm_btn
+cancel_btn
+is_displayed
}
class BaseChangeOrgLocModal {
+title
+menu_toggle
+success_alert
+error_alert
+is_displayed
}
class ChangeOrganizationModal {
+organization_menu
+organization_fix_on_mismatch
+organization_fail_on_mismatch
+save_button
+cancel_button
}
class ChangeLocationModal {
+location_menu
+location_fix_on_mismatch
+location_fail_on_mismatch
+save_button
+cancel_button
}
class MenuToggleSelect {
}
AllHostsEntity --> AllHostsTableView
AllHostsEntity --> ChangeHostsOwnerModal
AllHostsEntity --> ChangeOrganizationModal
AllHostsEntity --> ChangeLocationModal
ChangeOrganizationModal --|> BaseChangeOrgLocModal
ChangeLocationModal --|> BaseChangeOrgLocModal
ChangeHostsOwnerModal --> MenuToggleSelect
ChangeOrganizationModal --> MenuToggleSelect
ChangeLocationModal --> MenuToggleSelect
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
LadislavVasina1
requested review from
a team,
ColeHiggins2,
pnovotny,
pondrejk,
sambible,
vijaysawant and
vsedmik
July 21, 2025 09:39
Contributor
There was a problem hiding this comment.
Hey @LadislavVasina1 - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `airgun/entities/all_hosts.py:474` </location>
<code_context>
+ view = DisassociateHostsModal(self.browser)
+ view.confirm_btn.click()
+
+ def all_hosts_navigate_and_select_hosts_helper(self, host_names=None, select_all_hosts=False):
+ """
+ Helper function to navigate to All Hosts and select specified hosts or all hosts.
+ This function is used to avoid code duplication in methods that require host selection.
+
+ :param host_names: str with one host or list of hosts to select
+ :param select_all_hosts: bool, if True, all hosts will be selected
+
+ :raises ValueError: if both select_all_hosts and host_names are specified
+
+ :return: view (AllHostsTableView)
+ """
+
if select_all_hosts and host_names:
raise ValueError('Cannot select all and specify host names at the same time!')
</code_context>
<issue_to_address>
The helper does not handle the case where both host_names and select_all_hosts are falsy.
If neither host_names nor select_all_hosts is provided, the function navigates without selecting any hosts. If this is unintended, consider raising an error or documenting the expected behavior.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
if select_all_hosts and host_names:
raise ValueError('Cannot select all and specify host names at the same time!')
=======
if select_all_hosts and host_names:
raise ValueError('Cannot select all and specify host names at the same time!')
if not select_all_hosts and not host_names:
raise ValueError('Must specify either host_names or select_all_hosts.')
>>>>>>> REPLACE
</suggested_fix>
### Comment 2
<location> `airgun/entities/all_hosts.py:560` </location>
<code_context>
+ view.organization_fail_on_mismatch.fill(True)
+ view.save_button.click()
+
+ def change_associations_location(
+ self, host_names=None, new_location=None, select_all_hosts=False, option="Fix on mismatch"
+ ):
+ """
+ Navigate to change location modal after selecting number of hosts,
+ select desired location, select one of the options and apply changes.
+
+ :param host_names: str with one host or list of hosts to select
+ :param new_location: str location name which will be selected
+ :param select_all_hosts: select all hosts flag
+ :param option: str options either 'Fix on mismatch' or 'Fail on mismatch'
+ """
+
+ if new_location is None:
+ raise ValueError('new_location argument is None, it will not allow to Save changes')
+
</code_context>
<issue_to_address>
Redundant check for new_location before selecting location.
Since a ValueError is raised if new_location is None, the subsequent check is redundant and can be removed.
Suggested implementation:
```python
if new_location is None:
raise ValueError('new_location argument is None, it will not allow to Save changes')
```
```python
if new_location is None:
raise ValueError('new_location argument is None, it will not allow to Save changes')
```
</issue_to_address>
### Comment 3
<location> `airgun/views/all_hosts.py:615` </location>
<code_context>
return self.browser.wait_for_element(self.title, exception=False) is not None
+
+
+class MenuToggleSelect(PF5Select):
+ """
+ This class is PF5 implementation of the Select component within the new PF5 structure
+ Which is MenuToggle->Select and not just Select as it was in PF4.
+ """
+
+ BUTTON_LOCATOR = './/button[contains(@class, "pf-v5-c-menu-toggle")]'
+ DEFAULT_LOCATOR = (
+ './/div[contains(@class, "pf-v5-c-menu") and @data-ouia-component-type="PF5/Select"]'
+ )
+ ROOT = f"{BUTTON_LOCATOR}/.."
+ ITEMS_LOCATOR = ".//ul[contains(@class, 'pf-v5-c-menu__list')]/li"
+ ITEM_LOCATOR = (
+ "//*[contains(@class, 'pf-v5-c-menu__item') and .//*[contains(normalize-space(.), {})]]"
+ )
</code_context>
<issue_to_address>
ITEM_LOCATOR may not interpolate the item value as intended.
If ITEM_LOCATOR is meant for string formatting, ensure all usages apply .format(). Otherwise, consider refactoring it into a method or property that accepts the item value.
</issue_to_address>
### Comment 4
<location> `airgun/views/all_hosts.py:652` </location>
<code_context>
+ return self.browser.wait_for_element(self.title, exception=False) is not None
+
+
+class BaseChangeOrgLocModal(PF5Modal):
+ """
+ Base class representing the modal for changing organization or location.
+ """
+
+ title = './/h1[@class="pf-v5-c-modal-box__title"]'
+
+ menu_toggle = PF5Menu(locator='.//button[@class="pf-v5-c-menu-toggle"]')
+
+ success_alert = PF5Alert(
</code_context>
<issue_to_address>
menu_toggle locator may be too generic.
Consider refining the locator to target a specific menu toggle to prevent matching multiple elements in the modal.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
menu_toggle = PF5Menu(locator='.//button[@class="pf-v5-c-menu-toggle"]')
=======
menu_toggle = PF5Menu(locator='.//div[contains(@class, "pf-v5-c-modal-box")]//button[@class="pf-v5-c-menu-toggle"]')
>>>>>>> REPLACE
</suggested_fix>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Contributor
Author
|
PRT passed here SatelliteQE/robottelo#19030 |
vsedmik
approved these changes
Jul 21, 2025
vsedmik
left a comment
Contributor
There was a problem hiding this comment.
Looks good to me, left one non-blocking nit bellow.
vijaysawant
reviewed
Jul 21, 2025
vijaysawant
approved these changes
Jul 21, 2025
vijaysawant
left a comment
Contributor
There was a problem hiding this comment.
Please look at comment, rest of stuff is good.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds coverage for:
change the owner of multiple hosts(SAT-31026)change the location and organization of multiple hosts(SAT-31030)(@vijaysawant needed a backup with finishing the airgun coverage for this feature, so the additions regarding org and loc are inspired by all host change org and location airgun support #1927 and refactored)
This PR also introduces new function
all_hosts_navigate_and_select_hosts_helper.This function does repetitive navigation that is present almost everywhere in the
entities/all_hosts.py.In short, the function navigates to All Hosts and selects specified hosts or all hosts and does some assertion on the validity of calling this function.
I have tried to use this function on the places where I thought it might be beneficial.
I would like us to use this function forward when dealing with the entities navigation and host selection.
Needed by: SatelliteQE/robottelo#19030
Summary by Sourcery
Add bulk change owner, organization, and location actions for hosts and refactor host navigation selection logic.
New Features:
Enhancements: