.. _yaml-page-objects: ============================ Page Object Prototype Syntax ============================ .. contents:: Overview ======== To simplify the process of creating new page objects, some page object prototype classes support YAML representations of the object. Prototype classes that support this will generate a ``.yml`` file in addition to a Python module when using the ``new page --prototype `` command. The following sections detail YAML syntax specifically for ``webdriver_test_tools`` as well as the non-YAML alternative syntax for each :doc:`page object prototype `. For a basic introduction to YAML syntax in general, see `Ansible's YAML documentation`_. .. _Ansible's YAML documentation: https://docs.ansible.com/ansible/2.7/reference_appendices/YAMLSyntax.html Supported Prototype Classes --------------------------- The following prototype classes support YAML parsing: * :class:`FormObject ` * :class:`ModalObject ` * :class:`NavObject ` * :class:`WebPageObject ` When initialized, these classes check to see if the ``YAML_FILE`` attribute is set. If ``YAML_FILE`` is not ``None``, the contents will be parsed and used to set the page object's attributes. Configure Defaults ------------------ Whether YAML files or Python-only files are generated by default when using the ``new page`` command is configured in ``/config/projectfiles.py`` by setting the ``ENABLE_PAGE_OBJECT_YAML`` variable of the ``ProjectFilesConfig`` class. Override Default Setting ------------------------ The default setting can be overridden using command line arguments. If ``ENABLE_PAGE_OBJECT_YAML`` is ``True``, the ``--no-yaml`` (or ``-Y``) argument can be used to only generate ``.py`` files: :: new page --no-yaml If ``ENABLE_PAGE_OBJECT_YAML`` is ``False``, the ``--yaml`` (or ``-y``) argument can be used to generate ``.py`` and ``.yml`` files for supported prototypes: :: new page --yaml General Syntax ============== This section documents the syntax of general page object constructs. .. _yaml-locators: Locator Dictionaries -------------------- Element locators are represented by YAML dictionaries with the following required keys: * ``by``: Locator strategy to use when finding the element. Use variable names of attributes in ``selenium.webdriver.common.by.By``: * ``CLASS_NAME`` * ``CSS_SELECTOR`` * ``ID`` * ``LINK_TEXT`` * ``NAME`` * ``PARTIAL_LINK_TEXT`` * ``TAG_NAME`` * ``XPATH`` * ``locator``: Value used to locate element with the specified locator strategy .. note:: For non-YAML page objects, any instances of a locator dictionary can be replaced with a Python locator tuple i.e. ``(By., '')`` .. _yaml-relative-urls: Relative URL Dictionaries ------------------------- URLs that are relative to attributes specified in a project's ``SiteConfig`` are specified with dictionaries using the following keys: * ``path``: The path to the page, relative to the ``SiteConfig`` attribute specified in ``relative_to`` * ``relative_to``: A valid attribute declared in the project's ``SiteConfig`` class to use as a base URL .. note:: Internally, these URL dictionaries are parsed using :meth:`SiteConfig.parse_relative_url_dict `. If the attribute that ``relative_to`` specifies does not have a trailing '/', this method adds one before building the full URL .. todo document root keys for each .. _yaml-form-objects: FormObjects =========== :class:`FormObjects ` support YAML representations of the form element using the following syntax. Syntax ------ .. _yaml-forms: Forms ~~~~~ Form objects have 3 required keys: * ``form_locator``: :ref:`Locator dictionary ` for the ``
`` element * ``submit_locator``: :ref:`Locator dictionary ` for the form's submit button * ``inputs``: List of form :ref:`inputs ` .. _yaml-inputs: Inputs ~~~~~~ The items in the form ``inputs`` list have the following keys: * ``name``: **(Required)** The ``name`` attribute of the element. If the element doesn't have a name attribute, set this to any unique identifier (i.e. not used as the ``name`` value for another input in the form) * ``input_locator``: **(Required if element has no** ``name`` **attribute)** :ref:`Locator dictionary ` for the element. If provided, this will be used instead of ``name`` to find the element * ``type``: *(Default:* ``text`` *)* The ``type`` attribute of the input * ``required``: *(Default:* ``true`` *)* Whether or not the input is required to submit the form * ``options``: **(Required if** ``type`` **is** ``radio``, ``select``, **or a** ``checkbox`` **group (i.e. multiple checkboxes with the same name))** List of ``value`` attributes of radio inputs, select options, or checkboxes. A dictionary mapping values to labels is also valid (though only the map keys will be used, so the labels can be set to anything) Example ------- With YAML ~~~~~~~~~ .. literalinclude:: ../example/yaml-example/form.py :caption: form.py .. literalinclude:: ../example/yaml-example/form.yml :caption: form.yml Without YAML ~~~~~~~~~~~~ .. literalinclude:: ../example/no-yaml-example/form.py :caption: form.py .. _yaml-modal-objects: ModalObjects ============ :class:`ModalObjects ` support YAML representations of the modal using the following syntax. Syntax ------ Modal objects have 2 required keys: * ``modal_locator``: :ref:`Locator dictionary ` for the modal container element * ``close_locator``: :ref:`Locator dictionary ` for the modal close button Example ------- With YAML ~~~~~~~~~ .. literalinclude:: ../example/yaml-example/modal.py :caption: modal.py .. literalinclude:: ../example/yaml-example/modal.yml :caption: modal.yml Without YAML ~~~~~~~~~~~~ .. literalinclude:: ../example/no-yaml-example/modal.py :caption: modal.py .. _yaml-nav-objects: NavObjects ========== :class:`NavObjects ` support YAML representations of the nav using the following syntax. Syntax ------ .. _yaml-navs: Navbars ~~~~~~~ Navbar objects have the following keys: * ``links``: **(Required)** List of :ref:`links `. * ``fixed``: *(Default:* ``true`` *)* Whether or not the navbar is fixed to the screen * ``collapsible``: *(Default:* ``false`` *)* Whether or not the navbar is collapsible (e.g. for hamburger menus) * ``menu_locator``: **(Required if** ``collapsible`` **is** ``true`` **)** :ref:`Locator dictionary ` for the collapsible menu element * ``expand_button_locator``: **(Required if** ``collapsible`` **is** ``true`` **)** :ref:`Locator dictionary ` for the button that expands the menu * ``collapse_button_locator`` *(Optional)* Locator for the button that collapses the menu. Only needed if ``collapsible`` is ``true`` and the collapse button isn't the same as the expand button .. note:: It's possible to re-use the YAML from a non-collapsible navbar to create a collapsible variant. This can be useful for responsive navbars that collapse on mobile viewports. For an example of how to do this, see the :ref:`collapsible-nav-variant` example. .. _yaml-links: Links ~~~~~ The items in the nav ``links`` list have the following keys: * ``name``: **(Required)** Name used to refer to this link. Must be unique from other links in the same list * ``link_locator``: **(Required)** :ref:`Locator dictionary ` for the link element * ``click``: *(Default:* ``page`` *)* One of the following values describing the expected action on click: * ``page``: *(Default)* Go to another page * ``section``: Jump to a section in the current page * ``menu``: Toggle a dropdown menu * ``none``: No expected action * ``hover``: *(Default:* ``none`` *)* One of the following values describing the expected action on hover: * ``none``: *(Default)* No expected action * ``menu``: Show dropdown menu * ``target``: **(Required if** ``click`` **is** ``page`` **or** ``section`` **)** The link target, formatted in one of the following ways (depending on ``click`` type): * (``click: page``) The full URL to the target page * (``click: page``) :ref:`Relative URL dictionary ` with the path to the target page * (``click: section``) The ``id`` attribute of the section element (i.e. the link's ``href`` attribute) .. _yaml-nav-menus: * ``menu``: **(Required if** ``click`` **or** ``hover`` **is** ``menu`` **)** A dictionary representing the menu that appears on click or hover. Contains the following **required** keys: * ``menu_locator``: :ref:`Locator dictionary ` for the menu element * ``links``: List of :ref:`links `. Same syntax as the nav object links list Example ------- With YAML ~~~~~~~~~ Regular Navbar ^^^^^^^^^^^^^^ .. literalinclude:: ../example/yaml-example/nav.py :caption: nav.py .. literalinclude:: ../example/yaml-example/nav.yml :caption: nav.yml Collapsible Navbar ^^^^^^^^^^^^^^^^^^ .. literalinclude:: ../example/yaml-example/collapsible_nav.py :caption: collapsible_nav.py .. literalinclude:: ../example/yaml-example/collapsible_nav.yml :caption: collapsible_nav.yml .. _collapsible-nav-variant: Collapsible Navbar (Reusing YAML from Non-Collapsible) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. literalinclude:: ../example/yaml-example/collapsible_nav_variant.py :caption: collapsible_nav_variant.py Without YAML ~~~~~~~~~~~~ Regular Navbar ^^^^^^^^^^^^^^ .. literalinclude:: ../example/no-yaml-example/nav.py :caption: nav.py Collapsible Navbar ^^^^^^^^^^^^^^^^^^ .. literalinclude:: ../example/no-yaml-example/collapsible_nav.py :caption: collapsible_nav.py .. _yaml-web-page-objects: WebPageObjects ============== :class:`WebPageObjects ` support YAML representations of the modal using the following syntax. Syntax ------ Web page objects have one required key ``url``, which can be set to either the full URL to the page or a :ref:`relative URL dictionary ` .. note:: If 'url' is set to just the full URL to the page, the attribute ``PAGE_FILENAME`` will not be set in the ``WebPageObject``. If it is set to a dictionary, ``PAGE_FILENAME`` will be set to the value of 'path' Example ------- With YAML ~~~~~~~~~ .. literalinclude:: ../example/yaml-example/web_page.py :caption: web_page.py .. literalinclude:: ../example/yaml-example/web_page_full.yml :caption: web_page_full.yml .. literalinclude:: ../example/yaml-example/web_page_relative.yml :caption: web_page_relative.yml Without YAML ~~~~~~~~~~~~ .. literalinclude:: ../example/no-yaml-example/web_page.py :caption: web_page.py