Exemplo n.º 1
0
class GroupForm(Component):
    """Objects and methods for the Group Form component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('group-container')
    _cancel_button: Selector = Selectors.data_id('cancel-button')
    _delete_button: Selector = Selectors.data_id('delete-group-button')
    _name_field: Selector = Selectors.name('name')
    _save_button: Selector = Selectors.data_id('save-group-button')

    @property
    def cancel_button(self) -> WebElement:
        return self.container.find_element(*self._cancel_button)

    @property
    def delete_group_button(self) -> WebElement:
        return self.container.find_element(*self._delete_button)

    @property
    def name_field(self) -> WebElement:
        return self.container.find_element(*self._name_field)

    @property
    def save_button(self) -> WebElement:
        return self.container.find_element(*self._save_button)

    def fill_form(self, name: str) -> None:
        """Fill out a group form, then submit the form.

        :param name: The name of the group.
        """
        self.name_field.fill(name)
Exemplo n.º 2
0
class CancellationModal(Component):
    """Cancellation Modal component objects and methods for OnDemand applications.

    The cancellation modal may be accessed by selected 'Cancel' for a ride The modal may be found
    in the Ride Card or Ride Row kebab menus.
    """

    ROOT_LOCATOR: Selector = Selectors.data_id('cancellation-modal-container')
    _cancel_button: Selector = Selectors.data_id('cancellation-modal-cancel-button')
    _confirm_button: Selector = Selectors.data_id('cancellation-modal-confirm-button')
    _cancel_reason: Selector = Selectors.name('terminal-reason')

    @property
    def ride_cancel_input(self) -> WebElement:
        return self.container.find_element(*self._cancel_reason)

    @property
    def ride_cancel_confirm(self) -> WebElement:
        return self.container.find_element(*self._confirm_button)

    def cancel_ride(self, reason: str) -> None:
        """Cancel a ride, then wait for the cancellation modal to no longer be visible.

        :param reason: The cancellation reason for the ride.
        """
        self.ride_cancel_input.fill(reason)
        self.ride_cancel_confirm.click()

        self.wait_for_component_to_not_be_visible()
class BulkImportUsers(Base):
    """Objects and methods for the Bulk Import Users page."""

    ROOT_LOCATOR: Selector = Selectors.data_id(
        'bulk-import-users-page-container')
    _back_button: Selector = Selectors.data_id('back-button')
    _input_field: Selector = Selectors.element_type('file')
    _upload_list_button: Selector = Selectors.data_id(
        'upload-user-list-button')

    @property
    def back_button(self) -> WebElement:
        return self.driver.find_element(*self._back_button)

    @property
    def input_field(self) -> WebElement:
        return self.driver.find_element(*self._input_field)

    @property
    def upload_list_button(self) -> WebElement:
        return self.driver.find_element(*self._upload_list_button)

    @property
    def upload_user_list_modal(self) -> UploadUserListModal:
        return UploadUserListModal(self)

    def upload_file(self, file_name: str) -> None:
        """Upload a CSV list of test users for bulk import testing.

        :param file_name: The file name for upload.
        """
        _file_path: str = f'{os.getcwd()}/utilities/test_files/{file_name}'

        self.input_field.send_keys(_file_path)
Exemplo n.º 4
0
class Agency(Base):
    """Agency Page objects and methods for the OnDemand Web application."""

    ROOT_LOCATOR: Selector = Selectors.data_id('agency-page-container')
    _agency_email: Selector = Selectors.data_id('agency-email')
    _agency_name: Selector = Selectors.data_id('agency-name')
    _agency_phone: Selector = Selectors.data_id('agency-phone')
    _edit_agency_button: Selector = Selectors.data_id('edit-agency-button')

    @property
    def edit_agency_button(self) -> WebElement:
        return self.driver.find_element(*self._edit_agency_button)

    @property
    def email(self) -> str:
        return self.driver.find_element(*self._agency_email).text

    @property
    def name(self) -> str:
        return self.driver.find_element(*self._agency_name).text

    @property
    def phone(self) -> str:
        return self.driver.find_element(*self._agency_phone).text

    @property
    def service_list(self) -> ServiceList:
        return ServiceList(self)

    def edit_agency(self) -> object:
        """Open the agency select modal."""
        self.edit_agency_button.click()

        return AgencySelectModal(self).wait_for_component_to_be_present()
Exemplo n.º 5
0
class KebabMenu(Component):
    """Objects and methods for the Kebab Menu component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('kebab-menu-container')
    _delete_button: Selector = Selectors.data_id('delete-address')
    _edit_button: Selector = Selectors.data_id('edit-address')

    @property
    def delete_button(self) -> WebElement:
        return self.container.find_element(*self._delete_button)

    @property
    def edit_button(self) -> WebElement:
        return self.container.find_element(*self._edit_button)

    def delete_address(self) -> object:
        """Open the deletion modal for an address row."""
        self.delete_button.click()

        return DeletionModal(self).wait_for_component_to_be_present()

    def edit_address(self) -> object:
        """Open the edit address form for an address row.

        A conditional check for whether the URL contains 'admin' allows this method to be used in
        both OnDemand Web and OnDemand Admin.
        """
        self.edit_button.click()

        if 'admin' not in self.driver.current_url:
            return WebAddressForm(self).wait_for_component_to_be_present()
        return AdminAddressForm(self).wait_for_component_to_be_present()
Exemplo n.º 6
0
class EventsList(Component):
    """Ride Events List component objects and methods for the Details Page.

    The Ride Events List component contains ride event data within a container that can be found
    below the Ride Info Card on the Details page.
    """

    ROOT_LOCATOR: Selector = Selectors.data_id('details-events-container')
    _event_card: Selector = Selectors.data_id('details-event-card')

    @property
    def event_cards(self) -> Tuple[EventCard, ...]:
        """Return a list of all event cards within the event list container."""
        return tuple(
            EventCard(self.page, item)
            for item in self.container.find_elements(*EventCard.ROOT_LOCATOR))

    @property
    def ride_requested_card(self) -> EventCard:
        """Return the first card within the event list.

        The first card in the event list container should always be the Ride Requested card. This
        card contains ride data such as pick up and drop off locations.
        """
        return self.event_cards[0]
Exemplo n.º 7
0
class DeletionModal(Component):
    """Objects and methods for the Deletion Modal component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('remove-rider-modal-container')
    _cancel_button: Selector = Selectors.data_id('cancel-remove-rider-button')
    _confirm_button: Selector = Selectors.data_id('confirm-remove-rider-button')
    _message: Selector = Selectors.data_id('remove-rider-message')

    @property
    def cancel_button(self) -> WebElement:
        return self.container.find_element(*self._cancel_button)

    @property
    def confirm_button(self) -> WebElement:
        return self.container.find_element(*self._confirm_button)

    @property
    def delete_message(self) -> WebElement:
        return self.container.find_element(*self._message)

    def confirm_removal(self) -> None:
        """Confirm removal of a user from the group.

        Returns True if the container is no longer displayed. This should be used with an assert
        statement to verify it is True.
        """
        self.confirm_button.click()
        self.page.driver.wait_until_not_visible(*self.ROOT_LOCATOR)
Exemplo n.º 8
0
class AddressRow(Component):
    """Objects and methods for the Address Row component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('address-list-row')
    _address_id: Selector = Selectors.data_id('address-row-id')
    _data: Selector = Selectors.data_id('address-row-data')
    _kebab_button: Selector = Selectors.data_id('address-row-kebab-button')

    @property
    def address_id(self) -> str:
        """Return the unique address ID for an address row.

        The get_attribute method is used instead of .text as the ride_id is a hidden attribute.
        """
        return self.container.find_element(*self._address_id).get_attribute('innerText')

    @property
    def data(self) -> str:
        return self.container.find_element(*self._data).text

    @property
    def kebab_button(self) -> WebElement:
        return self.container.find_element(*self._kebab_button)

    @property
    def kebab_menu(self) -> KebabMenu:
        return KebabMenu(self)

    def open_kebab_menu(self) -> object:
        """Open the kebab menu for an address row."""
        self.kebab_button.click()

        return KebabMenu(self).wait_for_component_to_be_present()
Exemplo n.º 9
0
class GroupRow(Component):
    """Group Row component objects and methods for the Group Page."""

    ROOT_LOCATOR: Selector = Selectors.data_id('group-row')
    _group_id: Selector = Selectors.data_id('row-id')
    _group_name: Selector = Selectors.data_id('group-name')
    _kebab_button: Selector = Selectors.data_id('kebab-button')

    @property
    def group_id(self) -> str:
        """Return the unique group ID for a group row.

        The get_attribute method is used instead of .text as the row_id is a hidden attribute.
        """
        return self.container.find_element(*self._group_id).get_attribute('innerText')

    @property
    def kebab_button(self) -> WebElement:
        return self.container.find_element(*self._kebab_button)

    @property
    def kebab_menu(self) -> KebabMenu:
        return KebabMenu(self)

    @property
    def name(self) -> str:
        return self.container.find_element(*self._group_name).text

    def open_kebab_menu(self) -> object:
        """Open the kebab menu for an address row."""
        self.kebab_button.click()

        return KebabMenu(self).wait_for_component_to_be_visible()
Exemplo n.º 10
0
class KebabMenu(Component):
    """Objects and methods for the Kebab Menu component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('kebab-menu-container')
    _delete_button: Selector = Selectors.data_id('delete-vehicle')
    _edit_button: Selector = Selectors.data_id('edit-vehicle')

    @property
    def delete_button(self) -> WebElement:
        return self.container.find_element(*self._delete_button)

    @property
    def edit_button(self) -> WebElement:
        return self.container.find_element(*self._edit_button)

    def delete_vehicle(self) -> object:
        """Open the deletion modal for a vehicle row."""
        self.delete_button.click()

        return DeletionModal(self).wait_for_component_to_be_present()

    def edit_vehicle(self) -> object:
        """Open the edit view for a vehicle row."""
        self.edit_button.click()

        return VehicleForm(self).wait_for_component_to_be_present()
Exemplo n.º 11
0
class Header(Component):
    """Objects and methods for the Header container."""

    HELP_LINK: str = 'https://faq.transloc.com/'
    ROOT_LOCATOR: Selector = Selectors.data_id('header-container')
    _agency_drop_down: Selector = Selectors.data_id('agency-dropdown')
    _help_tab: Selector = Selectors.data_id('user-nav-help')
    _logout_tab: Selector = Selectors.data_id('user-nav-logout')
    _profile_tab: Selector = Selectors.data_id('user-nav-profile')

    @property
    def agency_drop_down(self) -> WebElement:
        return self.container.find_element(*self._agency_drop_down)

    @property
    def help_link(self) -> WebElement:
        return self.container.find_element(*self._help_tab)

    @property
    def logout_link(self) -> WebElement:
        return self.container.find_element(*self._logout_tab)

    @property
    def profile_link(self) -> WebElement:
        return self.container.find_element(*self._profile_tab)
class SubscriptionErrors(Component):
    """Objects and methods for subscription errors."""

    ROOT_LOCATOR: Selector = Selectors.data_id('subscription-errors-container')
    _subscription_error: Selector = Selectors.data_id('subscription-error')

    @property
    def subscription_errors(self) -> List[WebElement]:
        return self.container.find_elements(*self._subscription_error)
Exemplo n.º 13
0
class AddressInput(Component):
    """Objects and methods for the Address Input component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('ride-request-search')
    _pick_up_field: Selector = Selectors.value('Custom Pickup')
    _pick_up_submit: Selector = Selectors.data_id('pickup-submit')
    _drop_off_field: Selector = Selectors.value('Custom Drop-off')
    _drop_off_submit: Selector = Selectors.data_id('dropoff-submit')

    @property
    def drop_off_field(self) -> WebElement:
        return self.container.find_element(*self._drop_off_field)

    @property
    def drop_off_submit(self) -> WebElement:
        """Return the submit button.

        self.page.driver is used as the button exists outside of the address input container.
        """
        return self.page.driver.find_element(*self._drop_off_submit)

    @property
    def pick_up_field(self) -> WebElement:
        return self.container.find_element(*self._pick_up_field)

    @property
    def pick_up_submit(self) -> WebElement:
        """Return the submit button.

        self.page.driver is used as the button exists outside of the address input container.
        """
        return self.page.driver.find_element(*self._pick_up_submit)

    @property
    def suggestions(self) -> AutocompleteSuggestions:
        return AutocompleteSuggestions(self)

    def select_drop_off_location(self, drop_off: str) -> None:
        """Fill out a drop off location, then submit the location.

        :param drop_off: The drop off location for a ride.
        """
        self.drop_off_field.fill(drop_off)
        self.suggestions.select_suggestion(drop_off)

        self.drop_off_submit.click()

    def select_pick_up_location(self, pick_up: str) -> None:
        """Fill out a pick up location, then submit the location.

        :param pick_up: The pick up location for a ride.
        """
        self.pick_up_field.fill(pick_up)
        self.suggestions.select_suggestion(pick_up)

        self.pick_up_submit.click()
class RidePrioritizationModal(Component):
    """Ride Prioritization Modal component objects and methods for the Dispatch page.

    The prioritization modal may be accessed by selecting 'Prioritize' from a Ride Card kebab menu.
    """

    ROOT_LOCATOR: Selector = Selectors.data_id(
        'ride-prioritization-modal-container')
    _cancel_button: Selector = Selectors.data_id(
        'ride-prioritization-modal-cancel-button')
    _confirm_button: Selector = Selectors.data_id(
        'ride-prioritization-modal-confirm-button')
    _entire_ride_button: Selector = Selectors.data_id(
        'ride-prioritization-modal-entire-ride-button', )
    _pick_up_button: Selector = Selectors.data_id(
        'ride-prioritization-modal-pick-up-button')

    @property
    def cancel_button(self) -> WebElement:
        return self.container.find_element(*self._cancel_button)

    @property
    def confirm_button(self) -> WebElement:
        return self.container.find_element(*self._confirm_button)

    @property
    def entire_ride_button(self) -> WebElement:
        return self.container.find_element(*self._entire_ride_button)

    @property
    def pick_up_button(self) -> WebElement:
        return self.container.find_element(*self._pick_up_button)

    def prioritize_ride(self, priority_type: str) -> None:
        """Prioritize a ride based on an input type.

        'Drop off' is skipped due to the fact that the drop off selection does not feature a radio
        button like 'Entire ride' and 'Pick up'. Instead, 'Drop off' is selected by selecting the
        confirm button on the prioritization modal. Logically, when 'Drop off' is passed to this
        method, the confirm button will be selected.

        :param priority_type: The type of prioritization.
        """
        _accepted_types: List[str] = ['drop off', 'entire ride', 'pick up']

        if priority_type not in _accepted_types:
            raise PrioritizationException(
                f'The prioritization type: {priority_type} is invalid.')

        if priority_type == 'pick up':
            self.pick_up_button.click()
        elif priority_type == 'entire ride':
            self.entire_ride_button.click()
        self.confirm_button.click()

        self.driver.wait_until_not_present(*self.ROOT_LOCATOR)
Exemplo n.º 15
0
class EditForm(Component):
    """Edit Form component objects and methods for the Rides Info component.

    The Edit Form component contains tools for editing the pick up and drop off locations for a
    ride featured within the Details page. The Edit Form may be accessed from the Ride Info
    component.
    """

    ROOT_LOCATOR: Selector = Selectors.data_id('details-edit-ride-container')

    _pick_up_address: Selector = Selectors.name('pickup')
    _drop_off_address: Selector = Selectors.name('dropoff')
    _swap_button: Selector = Selectors.data_id('edit-swap-button')
    _update_button: Selector = Selectors.data_id('edit-update-button')
    _cancel_button: Selector = Selectors.data_id('edit-cancel-button')
    _total_passenger_field: Selector = Selectors.name('capacity')
    _wheelchair_check_box: Selector = Selectors.name('wheelchair')

    @property
    def cancel_button(self) -> WebElement:
        return self.container.find_element(*self._cancel_button)

    @property
    def drop_off_address(self) -> WebElement:
        return self.container.find_element(*self._drop_off_address)

    @property
    def pick_up_address(self) -> WebElement:
        return self.container.find_element(*self._pick_up_address)

    @property
    def schedule_form(self) -> ScheduleForm:
        return ScheduleForm(self)

    @property
    def swap_button(self) -> WebElement:
        return self.container.find_element(*self._swap_button)

    @property
    def total_passenger_field(self) -> WebElement:
        return self.container.find_element(*self._total_passenger_field)

    @property
    def update_button(self) -> WebElement:
        return self.container.find_element(*self._update_button)

    @property
    def wheelchair_check_box(self) -> WebElement:
        return self.container.find_element(*self._wheelchair_check_box)

    def swap_addresses(self) -> None:
        """Select the swap button, then save the edit."""
        self.swap_button.click()

        self.update_button.click()
Exemplo n.º 16
0
class KebabMenu(Component):
    """Objects and methods for a Ride Card Kebab Menu.

    The Kebab Menu allows administrators to cancel, prioritize, or edit rides.
    """

    ROOT_LOCATOR: Selector = Selectors.data_id('ride-card-kebab-menu')
    _cancel_ride_button: Selector = Selectors.data_id('kebab-cancel-ride')
    _disabled_prioritize_ride_button: Selector = Selectors.data_id(
        'kebab-disable-prioritize')
    _prioritize_ride_button: Selector = Selectors.data_id(
        'kebab-prioritize-ride')
    _ride_details_button: Selector = Selectors.data_id('kebab-ride-details')

    @property
    def cancel_ride_button(self) -> WebElement:
        return self.container.find_element(*self._cancel_ride_button)

    @property
    def prioritize_ride_button(self) -> WebElement:
        return self.container.find_element(*self._prioritize_ride_button)

    @property
    def ride_details_button(self) -> WebElement:
        return self.container.find_element(*self._ride_details_button)

    @property
    def ride_details_link(self) -> str:
        return self.ride_details_button.get_attribute('href')

    def prioritize_disabled(self) -> WebElement:
        return self.container.wait_until_present(
            *self._disabled_prioritize_ride_button)

    def navigate_to_ride_details(self) -> object:
        """Navigate to the Details Page link.

        Selecting the ride_details_link element opens a new tab. To get around this, we save the
        link URL, then input the str to the Web Driver.

        :returns Details: An instance of the Ride Details page.
        """
        ride_details_url = self.ride_details_link
        self.driver.get(ride_details_url)

        return Details(self.driver, ride_details_url).wait_for_page_to_load()

    def open_ride_prioritization_modal(self) -> object:
        """Find and open a ride card ride prioritization modal.

        :returns RidePrioritizationModal: An instance of the ride's Ride Prioritization Modal.
        """
        self.prioritize_ride_button.click()

        return RidePrioritizationModal(self).wait_for_component_to_be_visible()
Exemplo n.º 17
0
class RideSubscriptionDetailsModal(Component):
    """Objects and methods for the Ride Subscription Details modal."""

    ROOT_LOCATOR: Selector = Selectors.data_id(
        'subscription-modal-details-container')
    _back_button: Selector = Selectors.data_id(
        'subscription-modal-back-button')
    _cancel_all_button: Selector = Selectors.data_id(
        'subscription-modal-cancel-all')
    _summary: Selector = Selectors.data_id('subscription-modal-summary')

    @property
    def back_button(self) -> WebElement:
        return self.container.find_element(*self._back_button)

    @property
    def cancel_all_button(self) -> WebElement:
        return self.container.find_element(*self._cancel_all_button)

    @property
    def cancellation_modal(self) -> CancellationModal:
        return CancellationModal(self)

    @property
    def deletion_modal(self) -> DeletionModal:
        return DeletionModal(self)

    @property
    def ride_placard(self) -> RidePlacard:
        return RidePlacard(self)

    @property
    def scheduled_rides_list(self) -> ScheduledRidesList:
        return ScheduledRidesList(self)

    @property
    def summary(self) -> str:
        return self.container.find_element(*self._summary).text

    def cancel_all_rides(self, reason: str) -> None:
        """Cancel all scheduled rides for a recurring ride request.

        :param reason: The reason for cancelling a ride.
        """
        self.cancel_all_button.click()

        self.cancellation_modal.cancel_ride(reason)
        self.cancellation_modal.wait_for_component_to_not_be_visible()

    def delete_all_rides(self) -> None:
        """Delete all scheduled rides for a recurring ride request."""
        self.cancel_all_button.click()

        self.deletion_modal.confirm_button.click()
        self.deletion_modal.wait_for_component_to_not_be_visible()
Exemplo n.º 18
0
class VehicleRow(Component):
    """Vehicle Row component objects and methods for the Vehicles Page."""

    ROOT_LOCATOR: Selector = Selectors.data_id('vehicle-row')
    _color: Selector = Selectors.data_id('color')
    _enabled: Selector = Selectors.data_id('operational')
    _kebab_button: Selector = Selectors.data_id('kebab-button')
    _vehicle_call_name: Selector = Selectors.data_id('vehicle-call-name')
    _vehicle_capacity: Selector = Selectors.data_id('ambulatory-capacity')
    _vehicle_id: Selector = Selectors.data_id('row-id')
    _wheelchair_capacity: Selector = Selectors.data_id('accessible-capacity')
    _wheelchair_impact: Selector = Selectors.data_id('capacity-impact')

    @property
    def vehicle_id(self) -> str:
        """Return the unique vehicle ID for a vehicle row.

        The get_attribute method is used instead of .text as the vehicle_id is a hidden attribute.
        """
        return self.container.find_element(
            *self._vehicle_id).get_attribute('innerText')

    @property
    def color(self) -> WebElement:
        return self.container.find_element(*self._color)

    @property
    def enabled(self) -> str:
        return self.container.find_element(*self._enabled).text

    @property
    def kebab_button(self) -> WebElement:
        return self.container.find_element(*self._kebab_button)

    @property
    def kebab_menu(self) -> KebabMenu:
        return KebabMenu(self)

    @property
    def vehicle_call_name(self) -> str:
        return self.container.find_element(*self._vehicle_call_name).text

    @property
    def vehicle_capacity(self) -> str:
        return self.container.find_element(*self._vehicle_capacity).text

    @property
    def wheelchair_capacity(self) -> str:
        return self.container.find_element(*self._wheelchair_capacity).text

    @property
    def wheelchair_impact(self) -> str:
        return self.container.find_element(*self._wheelchair_impact).text

    def open_kebab_menu(self) -> object:
        """Open the kebab menu for a vehicle row."""
        self.kebab_button.click()

        return KebabMenu(self).wait_for_component_to_be_present()
class GroupRestrictionsModal(Component):
    """Objects and methods for the Restricted Groups modal."""

    ROOT_LOCATOR: Selector = Selectors.data_id('groups-modal-container')
    _manage_agency_groups_button: Selector = Selectors.data_id(
        'groups-manage-button')
    _no_groups_message: Selector = Selectors.data_id('no-user-groups-message')
    _save_button: Selector = Selectors.data_id('save-groups-modal-button')
    _cancel_button: Selector = Selectors.data_id('cancel-groups-modal-button')

    @property
    def manage_agency_button(self) -> WebElement:
        return self.container.find_element(*self._manage_agency_groups_button)

    @property
    def save_button(self) -> WebElement:
        return self.container.find_element(*self._save_button)

    @property
    def cancel_button(self) -> WebElement:
        return self.container.find_element(*self._cancel_button)

    @property
    def no_user_groups_message(self) -> str:
        return self.container.find_element(*self._no_groups_message).text

    @property
    def groups_rows(self) -> List[GroupRow]:
        return [
            GroupRow(self.page, item)
            for item in self.container.find_elements(*GroupRow.ROOT_LOCATOR)
        ]

    def filter_group_rows(self, group: dict) -> Union[GroupRow, None]:
        """Filter all groups for a match with a group id.

        :param group: The group intended to be raised.
        """
        groups_list: Tuple[GroupRow,
                           ...] = tuple(item for item in self.groups_rows
                                        if item.group_id == group['group_id'])

        if not groups_list:
            raise NoSuchElementException
        return groups_list[0]

    def surface_group_row(self, group: dict) -> GroupRow:
        """Raise a group row for later use.

        :param group: The group intended to be raised.
        """
        return self.filter_group_rows(group)
Exemplo n.º 20
0
class Regions(Resources):
    """Objects and methods for the Regions page.

    The regions page may be accessed by selecting the 'Regions' tab from the side navigation
    panel on the 'Resources' page.
    """

    URL_PATH: str = f'{Resources.URL_PATH}/regions'
    ROOT_LOCATOR: Selector = Selectors.data_id('content-container')
    _fab_button: Selector = Selectors.data_id('new-button')

    @property
    def fab_button(self) -> WebElement:
        return self.driver.find_element(*self._fab_button)
class UploadUserListModal(Component):
    """Objects and methods for the Upload User List Modal."""

    ROOT_LOCATOR: Selector = Selectors.data_id('upload-user-list-modal-container')
    _confirm_button: Selector = Selectors.data_id('upload-user-list-confirm-button')
    _message: Selector = Selectors.data_id('upload-user-list-message')

    @property
    def confirm_button(self) -> WebElement:
        return self.container.find_element(*self._confirm_button)

    @property
    def message(self) -> str:
        return self.container.find_element(*self._message).text
Exemplo n.º 22
0
class RideRow(Component):
    """Objects and methods for an individual Ride table row.

    Ride rows contain information for the ride, a cancellation button, and a details button.
    Selecting the cancellation button raises a modal while selecting the details button redirects
    to the Details page for the specific ride.
    """

    ROOT_LOCATOR: Selector = Selectors.data_id('rides-table-row')
    _ride_name: Selector = Selectors.data_id('ride-name')
    _ride_pickup_address: Selector = Selectors.data_id('ride-pickup-address')
    _ride_dropoff_address: Selector = Selectors.data_id('ride-dropoff-address')
    _ride_id: Selector = Selectors.data_id('ride-id')
    _ride_status: Selector = Selectors.data_id('ride-status')
    _ride_time: Selector = Selectors.data_id('ride-time')
    _ride_cancel_button: Selector = Selectors.data_id('ride-cancel-button')
    _ride_details_button: Selector = Selectors.data_id('ride-details-button')

    @property
    def ride_name(self) -> str:
        return self.container.find_element(*self._ride_name).text

    @property
    def ride_pickup_address(self) -> str:
        return self.container.find_element(*self._ride_pickup_address).text

    @property
    def ride_dropoff_address(self) -> str:
        return self.container.find_element(*self._ride_dropoff_address).text

    @property
    def ride_id(self) -> str:
        """Return the unique ride ID for a ride row.

        The get_attribute method is used instead of .text as the ride_id is a hidden attribute.
        """
        return self.container.find_element(
            *self._ride_id).get_attribute('innerText')

    @property
    def ride_status(self) -> str:
        return self.container.find_element(*self._ride_status).text

    @property
    def ride_time(self) -> str:
        return self.container.find_element(*self._ride_time).text

    @property
    def ride_cancel_button(self) -> WebElement:
        return self.container.find_element(*self._ride_cancel_button)

    @property
    def ride_details_button(self) -> WebElement:
        return self.container.find_element(*self._ride_details_button)
Exemplo n.º 23
0
class AddressForm(Component):
    """Objects and methods for the Address Form component.

    The address form is used in both editing and creating addresses. It may be accessed by selecting
    'EDIT' from an address kebab menu or by selecting the FAB button for creating a new address.
    """

    ROOT_LOCATOR: Selector = Selectors.data_id('address-form-container')
    _button_container: Selector = Selectors.data_id(
        'address-form-button-container')
    _cancel_button: Selector = Selectors.data_id('address-form-cancel-button')
    _label_input: Selector = Selectors.placeholder('Label')
    _location_input: Selector = Selectors.placeholder(
        'Search for a location...')
    _places_autocomplete_suggestion: Selector = Selectors.data_id(
        'places-autocomplete-suggestion')
    _save_button: Selector = Selectors.data_id('address-form-confirm-button')

    @property
    def button_container(self) -> WebElement:
        return self.container.find_element(*self._button_container)

    @property
    def cancel_button(self) -> WebElement:
        return self.button_container.find_element(*self._cancel_button)

    @property
    def label_input(self) -> WebElement:
        return self.container.find_element(*self._label_input)

    @property
    def location_input(self) -> WebElement:
        return self.container.find_element(*self._location_input)

    @property
    def save_button(self) -> WebElement:
        return self.button_container.find_element(*self._save_button)

    @property
    def suggestions(self) -> AutocompleteSuggestions:
        return AutocompleteSuggestions(self)

    def select_location(self, location: str) -> None:
        """Fill out an address location, then submit the location.

        :param location: The location for an address.
        """
        self.location_input.fill(location)
        self.suggestions.select_suggestion(location)
class RideBookingPanel(Component):
    """Objects and methods for the ride booking panel."""

    ROOT_LOCATOR: Selector = Selectors.data_id('book-a-ride-container')
    _book_a_ride_button: Selector = Selectors.data_id('book-a-ride-open')
    _close_book_a_ride_button: Selector = Selectors.data_id(
        'book-a-ride-close')
    _submit_ride_button: Selector = Selectors.data_id('book-ride-button')

    @property
    def book_a_ride_button(self) -> WebElement:
        return self.container.find_element(*self._book_a_ride_button)

    @property
    def close_book_a_ride_button(self) -> WebElement:
        return self.container.find_element(*self._close_book_a_ride_button)

    @property
    def future_ride_form(self) -> FutureRideForm:
        return FutureRideForm(self)

    @property
    def passenger_form(self) -> PassengerForm:
        return PassengerForm(self)

    @property
    def recurring_ride_form(self) -> RecurringRideForm:
        return RecurringRideForm(self)

    @property
    def ride_form(self) -> RideForm:
        return RideForm(self)

    @property
    def schedule_form(self) -> ScheduleForm:
        return ScheduleForm(self)

    @property
    def submit_ride_button(self) -> WebElement:
        return self.container.find_element(*self._submit_ride_button)

    def open_book_a_ride_form(self) -> None:
        """Open the book a ride form, then check that the close element exists."""
        self.container.wait_until_visible(*self._book_a_ride_button)
        self.book_a_ride_button.click()

    def submit_ride_form(self) -> None:
        """Submit a ride form."""
        self.submit_ride_button.click()
Exemplo n.º 25
0
class KebabMenu(Component):
    """Objects and methods for the Ride Subscription Table Kebab Menu component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('subscription-kebab-menu-container')

    _details_button: Selector = Selectors.data_id('subscription-kebab-details-button')
    _cancel_all_button: Selector = Selectors.data_id('subscription-kebab-cancel-all')

    @property
    def details_button(self) -> WebElement:
        return self.container.find_element(*self._details_button)

    @property
    def cancel_all_button(self) -> WebElement:
        return self.container.find_element(*self._cancel_all_button)
Exemplo n.º 26
0
class Locations(Base):
    """Locations Page objects and methods for the OnDemand Admin application.

    The Locations page may be accessed by navigating to the Services page, selecting a service, then
    selecting the map.
    """

    ROOT_LOCATOR: Selector = Selectors.data_id('locations-page-container')
    _addresses_list_button: Selector = Selectors.data_id('addresses-list-button')
    _back_button: Selector = Selectors.data_id('back-button')
    _regions_list_button: Selector = Selectors.data_id('regions-list-button')
    _save_button: Selector = Selectors.data_id('save-button')

    @property
    def addresses_button(self) -> WebElement:
        return self.driver.find_element(*self._addresses_list_button)

    @property
    def addresses_list(self) -> AddressesList:
        return AddressesList(self)

    @property
    def back_button(self) -> WebElement:
        return self.driver.find_element(*self._back_button)

    @property
    def regions_button(self) -> WebElement:
        return self.driver.find_element(*self._regions_list_button)

    @property
    def regions_list(self) -> RegionsList:
        return RegionsList(self)

    @property
    def save_button(self) -> WebElement:
        return self.driver.find_element(*self._save_button)

    def open_addresses_list(self) -> object:
        """Open the address list component."""
        self.addresses_button.click()

        return AddressesList(self).wait_for_component_to_be_present()

    def open_regions_list(self) -> object:
        """Open the region list component."""
        self.regions_button.click()

        return RegionsList(self).wait_for_component_to_be_present()
Exemplo n.º 27
0
class AssignedServicesList(Component):
    """Objects and methods for the Assigned Services List component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('assigned-services-container')

    @property
    def assigned_services(self) -> List[AssignedService]:
        return [
            AssignedService(self.page, item)
            for item in self.container.find_elements(
                *AssignedService.ROOT_LOCATOR)
        ]

    def filter_services(self, service_id: int) -> AssignedService:
        """Filter all assigned services for a match with a service ID.

        :param service_id: The unique service ID for an assigned service.
        """
        service_list: List[AssignedService] = [
            service for service in self.assigned_services
            if service.service_id == service_id
        ]

        if not service_list:
            raise NoSuchElementException(
                f'An assigned service matching service ID: {service_id} could not be found.',
            )
        return service_list[0]

    def surface_assigned_service(self, service_id: int) -> AssignedService:
        """Raise an assigned service for later use.

        :param service_id: The unique service ID for a service.
        """
        return self.filter_services(service_id)
Exemplo n.º 28
0
class ServiceList(Component):
    """Objects and methods for the Service List component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('service-list')

    @property
    def service_rows(self) -> Tuple[ServiceRow, ...]:
        rows: WebElements = self.container.find_elements(*ServiceRow.ROOT_LOCATOR)

        return tuple(ServiceRow(self, element) for element in rows)

    def filter_rows(self, service_id: str) -> ServiceRow:
        """Filter all service rows for a match with a service ID.

        :param service_id: The unique service ID.
        """
        service_list: Tuple[ServiceRow, ...] = tuple(
            row for row in self.service_rows if row.service_id == service_id
        )

        if not service_list:
            raise NoSuchElementException
        return service_list[0]

    def surface_service_row(self, service_id: str) -> ServiceRow:
        """Raise a service row that matches a service ID.

        :param service_id: The unique service ID.
        """
        return self.filter_rows(service_id)
Exemplo n.º 29
0
class RidesList(Component):
    """Objects and methods for the Rides List component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('ride-list-container')

    @property
    def ride_rows(self) -> Tuple[RideRow, ...]:
        rows: WebElements = self.container.find_elements(*RideRow.ROOT_LOCATOR)

        return tuple(RideRow(self, element) for element in rows)

    def filter_rows(self, ride_id: str) -> RideRow:
        """Filter all ride rows for a match with a ride id.

        :param ride_id: The unique ride ID for a ride.
        """
        row_list: Tuple[RideRow, ...] = tuple(row for row in self.ride_rows
                                              if row.ride_id == ride_id)

        if not row_list:
            raise NoSuchElementException
        return row_list[0]

    def surface_ride_row(self, ride_id: str) -> RideRow:
        """Raise a ride row that matches a ride id.

        :param ride_id: The unique ride ID for a ride.
        """
        return self.filter_rows(ride_id)
Exemplo n.º 30
0
class VehiclesList(Component):
    """Objects and methods for the Vehicles List component."""

    ROOT_LOCATOR: Selector = Selectors.data_id('vehicle-list-container')

    @property
    def vehicle_rows(self) -> Tuple[VehicleRow, ...]:
        return tuple(
            VehicleRow(self.page, element)
            for element in self.container.find_elements(
                *VehicleRow.ROOT_LOCATOR))

    def filter_rows(self, vehicle: dict) -> Union[VehicleRow, None]:
        """Filter all vehicle rows for a match with a vehicle call name.

        :param vehicle: A vehicle object yielded from a vehicle fixture.
        """
        call_name: str = vehicle['call_name']
        row_list: Tuple[VehicleRow,
                        ...] = tuple(row for row in self.vehicle_rows
                                     if row.vehicle_call_name == call_name)

        if not row_list:
            return None
        return row_list[0]

    def surface_vehicle_row(self, vehicle: dict) -> VehicleRow:
        """Raise a vehicle row for later use.

        :param vehicle: A vehicle object yielded from a vehicle fixture.
        """
        return self.filter_rows(vehicle)