Exemplo n.º 1
0
class OrganizationsView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h1[normalize-space(.)='Organizations']")
    new = Text("//a[contains(@href, '/organizations/new')]")
    table = Table(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        },
    )

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None
Exemplo n.º 2
0
class ProductsTableView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h2[contains(., 'Products')]")
    new = Text("//button[contains(@href, '/products/new')]")
    edit = Text(
        "//td/a[contains(@ui-sref, 'product.repositories') and contains(@href, 'products')]"
    )
    repo_discovery = Text("//button[contains(.,'Repo Discovery')]")
    actions = ActionsDropdown("//div[contains(@class, 'btn-group')]")
    table = Table('.//table', column_widgets={'Name': Text('./a')})
    dialog = ConfirmationDialog()

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None
Exemplo n.º 3
0
class ProvisioningTemplatesView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h1[text()='Provisioning Templates']")
    new = Button("Create Template")
    build_pxe_default = Button("Build PXE Default")
    table = Table(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        },
    )

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title, exception=False) is not None
Exemplo n.º 4
0
class VirtwhoConfiguresView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h1[text()='Virt-who Configurations']")
    new = Text("//a[contains(@href, '/foreman_virt_who_configure/configs/new')]")
    table = Table(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Status': VirtwhoConfigureStatus('.'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        },
    )

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title, exception=False) is not None
Exemplo n.º 5
0
class ProvisioningTemplatesView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h1[contains(., 'Provisioning Templates')]")
    new = Text("//a[contains(@href, '/templates/provisioning_templates/new')]")
    table = SatTable(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        }
    )

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(
            self.title, exception=False) is not None
Exemplo n.º 6
0
Arquivo: rhai.py Projeto: synkd/airgun
    class plan(ParametrizedView):
        """Parametrized view for a nested plan view. Takes plan name on instantiation"""

        PARAMETERS = ("plan_name", )
        ROOT = ParametrizedLocator(
            ".//h2[contains(normalize-space(.), {plan_name|quote})]/"
            "ancestor::div[contains(@id, 'maintenance-plan')]")

        title = Text(".")
        delete = Text(".//i[@tooltip='Delete this plan']")
        edit = Text(".//i[@tooltip='Click to edit this plan']")
        ansible_actions = ActionsDropdown(
            "//div[contains(@class, 'btn-group')][@ng-if='ansibleRunner']")
        export_csv = Button("Export CSV")
        add_actions = Button("Add actions")
Exemplo n.º 7
0
class SCAPPoliciesView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h1[text()='Compliance Policies']")
    new = Text("//a[contains(@href, '/compliance/policies/new')]")
    table = SatTable(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        }
    )

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(
            self.title, exception=False) is not None
Exemplo n.º 8
0
class ComputeProfilesView(BaseLoggedInView, SearchableViewMixin):
    title = Text('//*[(self::h1 or self::h5) and text()="Compute Profiles"]')
    new = Text('//a[text()="Create Compute Profile"]')
    table = Table(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        },
    )

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None
Exemplo n.º 9
0
class PartitionTablesView(BaseLoggedInView, SearchableViewMixin):

    title = Text("//h1[text()='Partition Tables']")
    new = Button("Create Partition Table")
    table = SatTable(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        })

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(
            self.title, exception=False) is not None
Exemplo n.º 10
0
class HostDetailsView(BaseLoggedInView):
    breadcrumb = BreadCrumb()

    @property
    def is_displayed(self):
        breadcrumb_loaded = self.browser.wait_for_element(
            self.breadcrumb, exception=False)
        return (
                breadcrumb_loaded
                and self.breadcrumb.locations[0] == 'All Hosts'
                and self.breadcrumb.read() != 'Create Host'
        )

    boot_disk = ActionsDropdown(
        "//div[contains(@class, 'btn-group')]"
        "[contains(., 'Boot')][not(*[self::div])]"
    )
    schedule_remote_job = ActionsDropdown(
        "//div[contains(@class, 'btn-group')]"
        "[contains(., 'Schedule')][not(*[self::div])]"
    )
    back = Text("//a[text()='Back']")
    edit = Text("//a[@id='edit-button']")
    clone = Text("//a[@id='clone-button']")
    build = Text("//a[@id='build-review']")
    delete = Text("//a[@id='delete-button']")
    audits_details = Text("//a[text()='Audits']")
    facts_details = Text("//a[text()='Facts']")
    yaml_dump = Text("//a[text()='YAML']")
    yaml_output = Text("//pre")
    content_details = Text("//a[text()='Content']")

    @View.nested
    class properties(SatTab):
        properties_table = SatTableWithUnevenStructure(
            locator="//table[@id='properties_table']")
Exemplo n.º 11
0
class ReportTemplatesView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h1[normalize-space(.)='Report Templates']")
    new = Button("Create Template")
    table = Table(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Locked': Text('.'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        },
    )

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title, exception=False) is not None
Exemplo n.º 12
0
class SCAPContentsView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h1[text()='SCAP Content']")
    new = Text("//a[contains(@href, 'scap_contents/new')]")
    table = SatTable(
        './/table',
        column_widgets={
            'Title': Text('./a'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        },
    )
    dialog = Pf4ConfirmationDialog()

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None
Exemplo n.º 13
0
class TrendsView(BaseLoggedInView):
    title = Text("//h1[text()='Trends']")
    welcome_page = Text("//div[@class='blank-slate-pf']")
    new = Text("//a[contains(@href, '/trends/new')]")
    table = Table('.//table',
                  column_widgets={
                      'Name':
                      Text('./a'),
                      'Action':
                      ActionsDropdown("./div[contains(@class, 'btn-group')]"),
                  })

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None
Exemplo n.º 14
0
 class overview(SatTab):
     job_status = Text(
         "//div[@id='job_invocations_chart_container']"
         "//*[name()='tspan'][contains(@class,'donut-title-small-pf')]")
     job_status_progress = Text(
         "//div[@id='job_invocations_chart_container']"
         "//*[name()='tspan'][contains(@class,'donut-title-big-pf')]")
     hosts_table = SatTable(
         './/table',
         column_widgets={
             'Host': Text('./a'),
             'Actions':
             ActionsDropdown("./div[contains(@class, 'btn-group')]"),
         })
     total_hosts = Text("//h2[contains(., 'Total hosts')]"
                        "/span[@class='card-pf-aggregate-status-count']")
Exemplo n.º 15
0
class HostGroupsView(BaseLoggedInView, SearchableViewMixin):
    title = Text(
        "//h1[contains(., 'Host Group Configuration') or text()='Host Groups']"
    )
    new = Text("//a[contains(@href, '/hostgroups/new')]")
    table = SatTable(
        './/table',
        column_widgets={
            'Name': Text("./a"),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        })

    @property
    def is_displayed(self):
        return (self.browser.wait_for_element(self.title, exception=False)
                is not None and self.browser.url.endswith('hostgroups'))
Exemplo n.º 16
0
class ComputeResourcesView(BaseLoggedInView, SearchableViewMixin):

    title = Text("//h1[text()='Compute Resources']")
    new = Text("//a[contains(@href, '/compute_resources/new')]")
    table = SatTable(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        })

    @property
    def is_displayed(self):
        """Check if the right page is displayed"""
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None
Exemplo n.º 17
0
class DiscoveryRulesView(BaseLoggedInView):
    title = Text("//h1[text()='Discovery Rules']")
    new = Text("//a[contains(@href, '/discovery_rules/new')]")
    table = SatTable(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Actions': ActionsDropdown(
                "./div[contains(@class, 'btn-group')]"),
        }
    )

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(
            self.title, exception=False) is not None
Exemplo n.º 18
0
class SCAPTailoringFilesView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h1[text()='Tailoring Files']")
    new = Text("//a[contains(@href, 'tailoring_files/new')]")
    table = Table(
        './/table',
        column_widgets={
            'Name':
            Text("./a[contains(@href, '/compliance/tailoring_files')]"),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        },
    )
    dialog = Pf4ConfirmationDialog()

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None
Exemplo n.º 19
0
class TasksView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h1[text()='Tasks']")
    focus = ActionsDropdown(
        "//div[./button[@id='tasks-dashboard-time-period-dropdown']]")
    table = SatTable(
        ".//div[@class='tasks-table']//table",
        column_widgets={
            'Action': Text('./a'),
        },
    )
    pagination = TaskPagination()

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None

    @View.nested
    class RunningChart(View):
        ROOT = ".//div[@id='running-tasks-card']"
        name = Text("./h2")
        total = PieChart("./div[@class='card-pf-body']")

    @View.nested
    class PausedChart(View):
        ROOT = ".//div[@id='paused-tasks-card']"
        name = Text("./h2")
        total = PieChart("./div[@class='card-pf-body']")

    @View.nested
    class StoppedChart(View):
        ROOT = ".//div[@id='stopped-tasks-card']"
        name = Text("./h2")
        table = Table(
            locator='.//table',
            column_widgets={
                'Total': Text('./button'),
            },
        )

    @View.nested
    class ScheduledChart(View):
        ROOT = ".//div[@id='scheduled-tasks-card']"
        name = Text("./h2")
        total = Text(".//div[@class='scheduled-data']")
Exemplo n.º 20
0
class ActivationKeyEditView(BaseLoggedInView):
    """View for the ActivationKeys Edit page"""

    breadcrumb = BreadCrumb()
    actions = ActionsDropdown("//div[contains(@class, 'btn-group')]")
    dialog = ConfirmationDialog()

    @property
    def is_displayed(self):
        breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb,
                                                          exception=False)
        return (breadcrumb_loaded
                and self.breadcrumb.locations[0] == 'Activation Keys'
                and self.breadcrumb.read() != 'New Activation Key')

    @View.nested
    class details(SatTab):
        name = EditableEntry(name='Name')
        description = EditableEntry(name='Description')
        hosts_limit = EditableLimitEntry(name='Host Limit')
        service_level = EditableEntrySelect(name='Service Level')
        lce = ParametrizedView.nested(LCESelectorGroup)
        content_view = EditableEntrySelect(name='Content View')

    @View.nested
    class subscriptions(SatTab):
        resources = View.nested(AddRemoveSubscriptionsView)

    @View.nested
    class repository_sets(SatTab):
        TAB_NAME = 'Repository Sets'
        table = Table(locator=".//table")

    @View.nested
    class host_collections(SatTab):
        TAB_NAME = 'Host Collections'
        resources = View.nested(AddRemoveResourcesView)

    @View.nested
    class content_hosts(SatTabWithDropdown):
        TAB_NAME = 'Associations'
        SUB_ITEM = 'Content Hosts'
        table = Table(locator=".//table")
Exemplo n.º 21
0
class ComputeResourcesView(BaseLoggedInView, SearchableViewMixin):

    title = Text(
        '//*[(self::h1 or self::h5) and normalize-space(.)="Compute Resources"]'
    )
    new = Text('//a[normalize-space(.)="Create Compute Resource"]')
    table = SatTable(
        './/table',
        column_widgets={
            'Name': Text('./a'),
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        },
    )

    @property
    def is_displayed(self):
        """Check if the right page is displayed"""
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None
Exemplo n.º 22
0
class ContentHostsView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h2[contains(., 'Content Hosts')]")
    export = Text(
        ".//a[contains(@class, 'btn')][contains(@href, 'content_hosts.csv')]")
    register = Text(".//button[@ui-sref='content-hosts.register']")
    actions = ActionsDropdown(".//div[contains(@class, 'btn-group')]")
    dialog = ConfirmationDialog()
    table = SatTable('.//table',
                     column_widgets={
                         0: Checkbox(locator="./input[@type='checkbox']"),
                         'Name': Text('./a'),
                         'Subscription Status': StatusIcon(),
                         'Installable Updates': InstallableUpdatesCellView(),
                     })

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None
Exemplo n.º 23
0
class ProductEditView(BaseLoggedInView):
    breadcrumb = BreadCrumb()
    actions = ActionsDropdown("//div[contains(@class, 'btn-group')]")
    dialog = ConfirmationDialog()

    @property
    def is_displayed(self):
        breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb,
                                                          exception=False)
        return (breadcrumb_loaded
                and self.breadcrumb.locations[0] == 'Products'
                and self.breadcrumb.read()
                not in ('New Product', 'Discover Repositories')
                and len(self.breadcrumb.locations) <= 3)

    @View.nested
    class details(SatTab):
        name = EditableEntry(name='Name')
        label = ReadOnlyEntry(name='Label')
        gpg_key = EditableEntrySelect(name='GPG Key')
        ssl_ca_cert = EditableEntrySelect(name='SSL CA Cert')
        ssl_client_cert = EditableEntrySelect(name='SSL Client Cert')
        ssl_client_key = EditableEntrySelect(name='SSL Client Key')
        description = EditableEntry(name='Description')
        repos_count = ReadOnlyEntry(name='Number of Repositories')
        tasks_count = ReadOnlyEntry(name='Active Tasks')
        sync_plan = EditableEntrySelect(name='Sync Plan')
        sync_state = ReadOnlyEntry(name='Sync State')

    @View.nested
    class repositories(SatTab):
        table = SatTable(
            locator=".//table",
            column_widgets={
                0:
                Checkbox(
                    locator="./input[@ng-change='itemSelected(repository)']"),
                'Name':
                Text("./a"),
            },
        )
Exemplo n.º 24
0
class AnsibleRolesView(BaseLoggedInView, SearchableViewMixin):
    """Main Ansible Roles view. Prior to importing any roles, only the import_button
    is present, without the search widget or table.
    """

    title = Text("//h1[contains(., text()='Ansible Roles')")
    import_button = Text("//a[contains(@href, '/ansible_roles/import')]")
    submit = Button('Submit')
    total_imported_roles = Text(
        ".//span[contains(@class, 'pagination-pf-items-total')]")
    table = Table(
        './/table',
        column_widgets={
            'Actions': ActionsDropdown("./div[contains(@class, 'btn-group')]"),
        },
    )
    pagination = Pagination()

    @property
    def is_displayed(self):
        return self.title.is_displayed and self.import_button.is_displayed
Exemplo n.º 25
0
class HostCollectionInstallErrataView(BaseLoggedInView, SearchableViewMixin):
    title = Text("//h4[contains(., 'Content Host Errata Management')]")
    search = TextInput(
        locator=".//input[@type='text' and @ng-model='errataFilter']")
    refresh = Text(locator=".//button[@ng-click='fetchErrata()']")
    install = ActionsDropdown("//span[contains(@class, 'btn-group')]"
                              "[button[contains(@class, 'btn') "
                              "and contains(@ng-click, 'showConfirm')]]")
    table = SatTable(
        ".//table",
        column_widgets={
            0: Checkbox(locator=".//input[@ng-model='erratum.selected']"),
            'Id': Text(locator="./a[@ng-click='transitionToErrata(erratum)']"),
        })
    dialog = ConfirmationDialog()

    @property
    def is_displayed(self):
        """The view is displayed when it's title exists"""
        return self.browser.wait_for_element(self.title,
                                             exception=False) is not None
Exemplo n.º 26
0
    class repository_sets(SatTab, SearchableViewMixin):
        TAB_NAME = 'Repository Sets'

        show_all = Checkbox(locator=".//input[contains(@ng-model, 'contentAccessModeAll')]")
        limit_to_lce = Checkbox(locator=".//input[contains(@ng-model, 'contentAccessModeEnv')]")
        actions = ActionsDropdown("//div[contains(@class, 'btn-group')]")

        table = SatTable(
            './/table',
            column_widgets={
                0: Checkbox(locator="./input[@type='checkbox']"),
                'Product Name': Text('./a'),
            },
        )

        def read(self):
            """Sometimes no checkboxes are checked off by default, selecting
            "Show All" in such case.
            """
            if self.show_all.read() is False and self.limit_to_lce.read() is False:
                self.show_all.fill(True)
            return super().read()
Exemplo n.º 27
0
class ProductEditView(BaseLoggedInView):
    return_to_all = Text("//a[text()='Products']")
    actions = ActionsDropdown("//div[contains(@class, 'btn-group')]")
    dialog = ConfirmationDialog()

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.return_to_all,
                                             exception=False) is not None

    @View.nested
    class details(SatTab):
        name = EditableEntry(name='Name')
        label = ReadOnlyEntry(name='Label')
        gpg_key = EditableEntrySelect(name='GPG Key')
        ssl_ca_cert = EditableEntrySelect(name='SSL CA Cert')
        ssl_client_cert = EditableEntrySelect(name='SSL Client Cert')
        ssl_client_key = EditableEntrySelect(name='SSL Client Key')
        description = EditableEntry(name='Description')
        repos_count = ReadOnlyEntry(name='Number of Repositories')
        tasks_count = ReadOnlyEntry(name='Active Tasks')
        sync_plan = EditableEntrySelect(name='Sync Plan')
Exemplo n.º 28
0
class HostCollectionEditView(BaseLoggedInView):
    breadcrumb = BreadCrumb()
    actions = ActionsDropdown("//div[contains(@class, 'btn-group')]")
    dialog = ConfirmationDialog()

    @property
    def is_displayed(self):
        breadcrumb_loaded = self.browser.wait_for_element(self.breadcrumb, exception=False)
        return (
            breadcrumb_loaded
            and self.breadcrumb.locations[0] == 'Host Collections'
            and self.breadcrumb.read() != 'New Host Collection'
        )

    @View.nested
    class details(SatTab):
        name = EditableEntry(name='Name')
        description = EditableEntry(name='Description')
        content_hosts = ReadOnlyEntry(
            locator=(
                ".//dt[contains(., 'Content Hosts')]/following-sibling"
                "::dd/a[not(contains(@class, 'ng-hide'))][1]"
            )
        )
        content_host_limit = EditableLimitEntry(name='Content Host Limit')
        # Package Installation, Removal, and Update
        manage_packages = Text(".//a[@ng-click='openPackagesModal()']")
        # Errata Installation
        install_errata = Text(".//a[@ng-click='openErrataModal()']")
        # Module Stream Installation, Removal, and Update
        manage_module_streams = Text(".//a[@ng-click='openModuleStreamsModal()']")
        # Change assigned Lifecycle Environment or Content View
        change_assigned_content = Text(".//a[@ng-click='openEnvironmentModal()']")

    @View.nested
    class hosts(SatTab):
        TAB_NAME = 'Hosts'

        resources = View.nested(AddRemoveResourcesView)
Exemplo n.º 29
0
class ActivationKeyEditView(BaseLoggedInView):
    return_to_all = Text("//a[text()='Activation Keys']")
    actions = ActionsDropdown("//div[contains(@class, 'btn-group')]")
    dialog = ConfirmationDialog()

    @property
    def is_displayed(self):
        return self.browser.wait_for_element(self.return_to_all,
                                             exception=False) is not None

    @View.nested
    class details(SatTab):
        name = EditableEntry(name='Name')
        description = EditableEntry(name='Description')
        hosts_limit = EditableLimitEntry(name='Host Limit')
        service_level = EditableEntrySelect(name='Service Level')
        lce = ParametrizedView.nested(LCESelectorGroup)
        content_view = EditableEntrySelect(name='Content View')

    @View.nested
    class subscriptions(SatTab):
        resources = View.nested(AddRemoveSubscriptionsView)

    @View.nested
    class repository_sets(SatTab):
        TAB_NAME = 'Repository Sets'
        table = SatTable(locator=".//table")

    @View.nested
    class host_collections(SatTab):
        TAB_NAME = 'Host Collections'
        resources = View.nested(AddRemoveResourcesView)

    @View.nested
    class content_hosts(SatTabWithDropdown):
        TAB_NAME = 'Associations'
        SUB_ITEM = 'Content Hosts'
        table = SatTable(locator=".//table")
Exemplo n.º 30
0
    class errata(SatTab):
        lce_filter = Select(
            locator='.//select[@ng-model="selectedErrataOption"]')
        searchbox = Search()
        apply_selected = ActionsDropdown(
            ".//span[contains(@class, 'btn-group')]")
        recalculate = Button('Recalculate')
        table = SatTable(
            './/table',
            column_widgets={
                0: Checkbox(locator="./input[@type='checkbox']"),
                'Id': Text('./a'),
            },
        )
        select_all = Checkbox(
            locator=".//input[@type='checkbox'][@ng-change='allSelected()']")
        pagination = Pagination()

        def search(self, query, lce=None):
            """Apply available filters before proceeding with searching and
            automatically set proper search mask if errata id instead of errata
            title was passed.

            :param str query: search query to type into search field. Both
                errata id (RHEA-2012:0055) and errata title (Sea_Erratum) are
                supported.
            :param str optional lce: filter by lifecycle environment
            :return: list of dicts representing table rows
            :rtype: list
            """
            if lce is not None:
                self.lce_filter.fill(lce)

            if re.search(r'\w{4}-\d{4}:\d{4}', query):
                query = f'id = {query}'
            self.searchbox.search(query)

            return self.table.read()