def test_out_of_bound_widgets(web_fixture): """When you need to add a widget to the page, but not as a child/descendant.""" class MyPanel(Div): def __init__(self, view): super().__init__(view, css_id='main_panel') child_widget = self.add_child(P(view, text='Child Widget')) out_of_bound_widget = view.add_out_of_bound_widget( P(view, text='Out Of Bound Widget')) class MainUI(UserInterface): def assemble(self): self.define_page(HTML5Page).use_layout(BasicPageLayout()) home = self.define_view('/', title='Hello') home.set_slot('main', MyPanel.factory()) fixture = web_fixture wsgi_app = fixture.new_wsgi_app(site_root=MainUI) browser = Browser(wsgi_app) browser.open('/') main_panel = XPath.div().with_id('main_panel') assert browser.is_element_present( XPath.paragraph().with_text('Out Of Bound Widget')) assert not browser.is_element_present(XPath.paragraph().with_text( 'Out Of Bound Widget').inside_of(main_panel)) assert browser.is_element_present( XPath.paragraph().with_text('Child Widget').inside_of(main_panel))
def test_chartplotly(web_fixture, plotly_scenario): fixture = plotly_scenario browser = web_fixture.driver_browser fixture.start_example_app() browser.open('/') assert browser.is_element_present(XPath.div().including_class('js-plotly-plot'))
def test_alert_for_domain_exception(web_fixture): """FormLayout can be used to add an Alert with error messages to a form. This includes a 'Reset input' button which clears the form input. """ class ModelObject: @exposed def fields(self, fields): fields.some_field = Field(label='Some field', default='not changed') @exposed def events(self, events): events.submit_break = Event(label='Submit', action=Action(self.always_break)) def always_break(self): raise ValidationException(message='designed to break') class MyForm(Form): def __init__(self, view): super().__init__(view, 'myform') self.use_layout(FormLayout()) model_object = ModelObject() if self.exception: self.layout.add_alert_for_domain_exception(self.exception) self.layout.add_input( TextInput(self, model_object.fields.some_field)) self.define_event_handler(model_object.events.submit_break) self.add_child(Button(self, model_object.events.submit_break)) wsgi_app = web_fixture.new_wsgi_app(child_factory=MyForm.factory()) web_fixture.reahl_server.set_app(wsgi_app) browser = web_fixture.driver_browser browser.open('/') browser.type(XPath.input_labelled('Some field'), 'some input given') browser.click(XPath.button_labelled('Submit')) alert = XPath.div().including_class('alert') assert browser.is_element_present(alert) assert browser.get_text(alert) == 'designed to break' assert browser.get_value( XPath.input_labelled('Some field')) == 'some input given' browser.click(XPath.button_labelled('Reset input')) assert not browser.is_element_present(alert) assert browser.get_value( XPath.input_labelled('Some field')) == 'not changed'
def test_dynamicerrors(web_fixture, dynamiccontenterrors_scenario): fixture = dynamiccontenterrors_scenario browser = web_fixture.driver_browser fixture.start_example_app() browser.open('/') browser.select(XPath.select_named('dynamic_content_error_form-operator'), '÷'); error_alert = XPath.div().including_class('alert').including_text('I can\'t divide by 0') assert not browser.is_element_present(error_alert) browser.type(XPath.input_named('dynamic_content_error_form-operand_b'), '0') assert browser.is_element_present(error_alert) assert browser.is_element_present(XPath.span().including_text('---'))
def test_domain_exception(web_fixture, session_scope_fixture): """Typing the wrong password results in an error message being shown to the user.""" browser = Browser(web_fixture.new_wsgi_app(site_root=SessionScopeUI)) user = session_scope_fixture.user browser.open('/') browser.click(XPath.link().with_text('Log in')) browser.type(XPath.input_labelled('Email'), '*****@*****.**') browser.type(XPath.input_labelled('Password'), 'wrong password') browser.click(XPath.button_labelled('Log in')) assert browser.is_element_present( XPath.div().including_text('The email/password given do not match'))
def test_domain_exception(web_fixture, login_fixture): """Typing the wrong password results in an error message being shown to the user.""" browser = login_fixture.browser login_fixture.new_account() browser.open('/') browser.click(XPath.link().with_text('Log in')) browser.type(XPath.input_labelled('Email'), '*****@*****.**') browser.type(XPath.input_labelled('Password'), 'wrong password') browser.click(XPath.button_labelled('Log in')) assert browser.is_element_present( XPath.div().including_text('Invalid login credentials'))
def test_optimisticconcurrency(web_fixture, optimisticconcurrency_scenario): fixture = optimisticconcurrency_scenario browser = web_fixture.driver_browser fixture.start_example_app() browser.open('/') with browser.new_tab_closed(): browser.click(XPath.link().with_text('Open another tab...')) browser.switch_to_different_tab() browser.click(XPath.button_labelled('Increment')) browser.click(XPath.button_labelled('Submit')) error_alert = XPath.div().including_class('alert').including_text('Some data changed since you opened this page') assert browser.is_element_present(error_alert) browser.capture_cropped_screenshot(fixture.new_screenshot_path('optimisticconcurrency.png'))
def with_builtin_error_page(self): self.root_ui = BreakingUIWithBuiltInErrorPage self.expected_error_text = 'An error occurred:\nThis error is thrown intentionally\nOk' self.error_element = XPath.div().including_class('alert')
def is_any_error_displayed(self): return self.web_fixture.driver_browser.is_element_present( XPath.div().including_class('errors'))
def new_domain_exception_alert(self): return XPath.div().including_class('alert').with_text( 'Please ensure allocation percentages add up to 100')
def check_concurrency_error_is_displayed(self): alert = XPath.div().including_class('alert') assert 'Some data changed since you opened this page' in self.browser.get_text( alert)
def check(browser): assert browser.is_element_present( XPath.heading(1).with_text('An error occurred:').inside_of( XPath.div()))
# GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from reahl.tofu import scenario, Fixture, uses, expected from reahl.tofu.pytestsupport import with_fixtures from reahl.browsertools.browsertools import XPath, Browser from reahl.web_dev.fixtures import WebFixture from reahl.web.ui import Div, Form, FormLayout, SelectInput, exposed, ChoiceField, Choice from reahl.component.modelinterface import Field, IntegerField from reahl.web.plotly import Chart import plotly.graph_objects as go chart = XPath.div().including_class('js-plotly-plot') plotly_js = XPath('//script[contains(@src,"static/plotly")]') @with_fixtures(WebFixture) def test_plotly_basics(web_fixture): """How to add a Chart widget to a page.""" fig = go.Figure() wsgi_app = web_fixture.new_wsgi_app(child_factory=Chart.factory( fig, 'unique_id'), enable_js=True) web_fixture.reahl_server.set_app(wsgi_app) browser = web_fixture.driver_browser browser.open('/')