yashaka / selene

User-oriented Web UI browser tests in Python

Home Page:https://yashaka.github.io/selene/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

consider pydantic style of PageObjects

yashaka opened this issue · comments

Example:

class ReactContinuousSlider(selene.PageModel):
    config = selene.PageModel.Config(url='https://mui.com/material-ui/react-slider/#ContinuousSlider')
    container = selene.PageModel.Element('#ContinuousSlider+*')
    thumb = container.element('.MuiSlider-thumb')
    thumb_input = thumb.element('input')
    volume_up = container.element('[data-testid=VolumeUpIcon]')
    volume_down = container.element('[data-testid=VolumeDownIcon]')
    rail = container.element('.MuiSlider-rail')


reactSlider = ReactContinuousSlider(browser).open()

reactSlider.thumb.perform(command.drag_and_drop_to(reactSlider.volume_up))
reactSlider.thumb_input.should(have.value('100'))

reactSlider.thumb.perform(command.drag_and_drop_to(reactSlider.volume_down))
reactSlider.thumb_input.should(have.value('0'))

reactSlider.thumb.perform(command.drag_and_drop_to(reactSlider.rail))
reactSlider.thumb_input.should(have.value('50'))

as a shortcut to

class ReactContinuousSlider:
    def __init__(self, browser: selene.Browser | None):
        self.browser = browser if browser else selene.browser
        self.container = self.browser.element('#ContinuousSlider+*')
        self.thumb = self.container.element('.MuiSlider-thumb')
        self.thumb_input = self.thumb.element('input')
        self.volume_up = self.container.element('[data-testid=VolumeUpIcon]')
        self.volume_down = self.container.element('[data-testid=VolumeDownIcon]')
        self.rail = self.container.element('.MuiSlider-rail')

    def open(self):
        self.browser.open('https://mui.com/material-ui/react-slider/#ContinuousSlider')
        return self


reactSlider = ReactContinuousSlider(browser).open()

reactSlider.thumb.perform(command.drag_and_drop_to(reactSlider.volume_up))
reactSlider.thumb_input.should(have.value('100'))

reactSlider.thumb.perform(command.drag_and_drop_to(reactSlider.volume_down))
reactSlider.thumb_input.should(have.value('0'))

reactSlider.thumb.perform(command.drag_and_drop_to(reactSlider.rail))
reactSlider.thumb_input.should(have.value('50'))

consider also simplifying container = selene.PageModel.Element('#ContinuousSlider+*') to container = selene.Element('#ContinuousSlider+*')

P.S. related to #439

Pay attention to difference between init and class attributes
https://stackoverflow.com/questions/46720838/python-init-vs-class-attributes
As far as I understand it:
If you will need by somehow more than one instance of class, then it will rewrite all attributes of the first instance.

Pay attention to difference between init and class attributes https://stackoverflow.com/questions/46720838/python-init-vs-class-attributes As far as I understand it: If you will need by somehow more than one instance of class, then it will rewrite all attributes of the first instance.

It will not, because they are not class attributes. In both python dataclasses and pydantic-based classes – the attributes that you define on the class level – are not class attributes – they are instance attributes. This is the main idea of such type of DSL.