import sys
import bs4
import pytest
import setpath # noqa:F401, must come before 'import mechanicalsoup'
from utils import setup_mock_browser
import mechanicalsoup
def test_construct_form_fail():
"""Form objects must be constructed from form html elements."""
soup = bs4.BeautifulSoup('This is not a form', 'lxml')
tag = soup.find('notform')
assert isinstance(tag, bs4.element.Tag)
with pytest.warns(FutureWarning, match="from a 'notform'"):
mechanicalsoup.Form(tag)
def test_submit_online(httpbin):
"""Complete and submit the pizza form at http://httpbin.org/forms/post """
browser = mechanicalsoup.Browser()
page = browser.get(httpbin + "/forms/post")
form = mechanicalsoup.Form(page.soup.form)
input_data = {"custname": "Philip J. Fry"}
form.input(input_data)
check_data = {"size": "large", "topping": ["cheese"]}
form.check(check_data)
check_data = {"size": "medium", "topping": "onion"}
form.check(check_data)
form.textarea({"comments": "warm"})
form.textarea({"comments": "actually, no, not warm"})
form.textarea({"comments": "freezer"})
response = browser.submit(form, page.url)
# helpfully the form submits to http://httpbin.org/post which simply
# returns the request headers in json format
json = response.json()
data = json["form"]
assert data["custname"] == "Philip J. Fry"
assert data["custtel"] == "" # web browser submits "" for input left blank
assert data["size"] == "medium"
assert data["topping"] == ["cheese", "onion"]
assert data["comments"] == "freezer"
def test_submit_set(httpbin):
"""Complete and submit the pizza form at http://httpbin.org/forms/post """
browser = mechanicalsoup.Browser()
page = browser.get(httpbin + "/forms/post")
form = mechanicalsoup.Form(page.soup.form)
form["custname"] = "Philip J. Fry"
form["size"] = "medium"
form["topping"] = ("cheese", "onion")
form["comments"] = "freezer"
response = browser.submit(form, page.url)
# helpfully the form submits to http://httpbin.org/post which simply
# returns the request headers in json format
json = response.json()
data = json["form"]
assert data["custname"] == "Philip J. Fry"
assert data["custtel"] == "" # web browser submits "" for input left blank
assert data["size"] == "medium"
assert data["topping"] == ["cheese", "onion"]
assert data["comments"] == "freezer"
@pytest.mark.parametrize("expected_post", [
pytest.param(
[
('text', 'Setting some text!'),
('comment', 'Testing preview page'),
('preview', 'Preview Page'),
], id='preview'),
pytest.param(
[
('text', '= Heading =\n\nNew page here!\n'),
('comment', 'Created new page'),
('save', 'Submit changes'),
], id='save'),
pytest.param(
[
('text', '= Heading =\n\nNew page here!\n'),
('comment', 'Testing choosing cancel button'),
('cancel', 'Cancel'),
], id='cancel'),
])
def test_choose_submit(expected_post):
browser, url = setup_mock_browser(expected_post=expected_post)
browser.open(url)
form = browser.select_form('#choose-submit-form')
browser['text'] = dict(expected_post)['text']
browser['comment'] = dict(expected_post)['comment']
form.choose_submit(expected_post[2][0])
res = browser.submit_selected()
assert res.status_code == 200 and res.text == 'Success!'
@pytest.mark.parametrize("value", [
pytest.param('continue', id='first'),
pytest.param('cancel', id='second'),
])
def test_choose_submit_from_selector(value):
"""Test choose_submit by passing a CSS selector argument."""
text = """
"""
browser, url = setup_mock_browser(expected_post=[('do', value)], text=text)
browser.open(url)
form = browser.select_form()
submits = form.form.select(f'input[value="{value}"]')
assert len(submits) == 1
form.choose_submit(submits[0])
res = browser.submit_selected()
assert res.status_code == 200 and res.text == 'Success!'
choose_submit_fail_form = '''
'''
@pytest.mark.parametrize("select_name", [
pytest.param({'name': 'does_not_exist', 'fails': True}, id='not found'),
pytest.param({'name': 'test_submit', 'fails': False}, id='found'),
])
def test_choose_submit_fail(select_name):
browser = mechanicalsoup.StatefulBrowser()
browser.open_fake_page(choose_submit_fail_form)
form = browser.select_form('#choose-submit-form')
if select_name['fails']:
with pytest.raises(mechanicalsoup.utils.LinkNotFoundError):
form.choose_submit(select_name['name'])
else:
form.choose_submit(select_name['name'])
def test_choose_submit_twice():
"""Test that calling choose_submit twice fails."""
text = '''
'''
soup = bs4.BeautifulSoup(text, 'lxml')
form = mechanicalsoup.Form(soup.form)
form.choose_submit('test1')
expected_msg = 'Submit already chosen. Cannot change submit!'
with pytest.raises(Exception, match=expected_msg):
form.choose_submit('test2')
choose_submit_multiple_match_form = '''
'''
def test_choose_submit_multiple_match():
browser = mechanicalsoup.StatefulBrowser()
browser.open_fake_page(choose_submit_multiple_match_form)
form = browser.select_form('#choose-submit-form')
with pytest.raises(mechanicalsoup.utils.LinkNotFoundError):
form.choose_submit('test_submit')
submit_form_noaction = '''
'''
def test_form_noaction():
browser, url = setup_mock_browser()
browser.open_fake_page(submit_form_noaction, url=url)
form = browser.select_form('#choose-submit-form')
form['text1'] = 'newText1'
res = browser.submit_selected()
assert res.status_code == 200 and browser.url == url
submit_form_action = '''
'''
def test_form_action():
browser, url = setup_mock_browser()
# for info about example.com see: https://tools.ietf.org/html/rfc2606
browser.open_fake_page(submit_form_action,
url="http://example.com/invalid/")
form = browser.select_form('#choose-submit-form')
form['text1'] = 'newText1'
res = browser.submit_selected()
assert res.status_code == 200 and browser.url == url
set_select_form = '''
'''
@pytest.mark.parametrize("option", [
pytest.param({'result': [('entree', 'tofu')], 'default': True},
id='default'),
pytest.param({'result': [('entree', 'curry')], 'default': False},
id='selected'),
])
def test_set_select(option):
'''Test the branch of Form.set that finds "select" elements.'''
browser, url = setup_mock_browser(expected_post=option['result'],
text=set_select_form)
browser.open(url)
browser.select_form('form')
if not option['default']:
browser[option['result'][0][0]] = option['result'][0][1]
res = browser.submit_selected()
assert res.status_code == 200 and res.text == 'Success!'
set_select_multiple_form = '''
'''
@pytest.mark.parametrize("options", [
pytest.param('bass', id='select one (str)'),
pytest.param(('bass',), id='select one (tuple)'),
pytest.param(('piano', 'violin'), id='select two'),
])
def test_set_select_multiple(options):
"""Test a