-
Notifications
You must be signed in to change notification settings - Fork 12
/
tests_functional.py
283 lines (240 loc) · 13.6 KB
/
tests_functional.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
import os
import time
import pytest
import requests
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.chrome.options import Options
BROWSER = os.environ.get('BROWSER', 'ChromeHeadless')
@pytest.fixture(scope="module")
def browser(request):
if BROWSER == 'ChromeHeadless':
chrome_options = Options()
chrome_options.add_argument("--headless")
browser = webdriver.Chrome(chrome_options=chrome_options)
else:
browser = getattr(webdriver, BROWSER)()
browser.implicitly_wait(3)
request.addfinalizer(lambda: browser.quit())
return browser
@pytest.fixture(scope="module")
def server_url(request, live_server):
if 'CUSTOM_SERVER_URL' in os.environ:
return os.environ['CUSTOM_SERVER_URL']
else:
return live_server.url
def test_accordion(server_url, browser):
browser.get(server_url)
def buttons():
return [b.is_displayed() for b in browser.find_elements_by_tag_name('button')]
time.sleep(0.5)
assert buttons() == [True, False, False]
assert 'Upload a file (.csv, .xlsx, .xml)' in browser.find_elements_by_tag_name('label')[0].text
browser.find_element_by_partial_link_text('Link').click()
browser.implicitly_wait(1)
time.sleep(0.5)
assert buttons() == [False, True, False]
browser.find_element_by_partial_link_text('Paste').click()
time.sleep(0.5)
assert buttons() == [False, False, True]
assert 'Paste (XML only)' in browser.find_elements_by_tag_name('label')[2].text
# Now test that the whole banner is clickable
browser.find_element_by_id('headingOne').click()
time.sleep(0.5)
assert buttons() == [True, False, False]
browser.find_element_by_id('headingTwo').click()
time.sleep(0.5)
assert buttons() == [False, True, False]
browser.find_element_by_id('headingThree').click()
time.sleep(0.5)
assert buttons() == [False, False, True]
def test_index_page_iati(server_url, browser):
browser.get(server_url)
assert 'How to use IATI CoVE' in browser.find_element_by_tag_name('body').text
assert 'XML - according to version 2.03 of the IATI schema' in browser.find_element_by_tag_name('body').text
assert 'Spreadsheet - Excel, CSV (UTF-8, Windows-1252 and ISO-8859-1 encodings supported) - see sample data' in browser.find_element_by_tag_name('body').text
@pytest.mark.parametrize(('link_text', 'url'), [
('IATI schema', 'http://reference.iatistandard.org/203/schema/')
])
def test_index_page_iati_links(server_url, browser, link_text, url):
browser.get(server_url)
link = browser.find_element_by_link_text(link_text)
href = link.get_attribute("href")
assert url in href
@pytest.mark.parametrize(('link_text', 'url'), [
('xlsx', 'https://docs.google.com/spreadsheets/d/1V8Cs4rivr6HDiDsne2bVECJiAXHcHBDiy_JEU9oPgRQ/export?format=xlsx'),
('convert to spreadsheet', '?source_url=https://raw.githubusercontent.com/OpenDataServices/iati-sample-data/master/IATI-CoVE-sample-activity-standard.xml?raw=true'),
('xml', 'https://github.com/OpenDataServices/iati-sample-data/blob/master/IATI-CoVE-sample-activity-standard.xml'),
('convert to xml', '?source_url=https://docs.google.com/spreadsheets/d/1WkCin68arZkAIhjxmKkml0MAskLcw9mkHctNmB_gH2I/export?format=xlsx'),
('google doc', 'https://docs.google.com/spreadsheets/d/1V8Cs4rivr6HDiDsne2bVECJiAXHcHBDiy_JEU9oPgRQ/edit?usp=sharing'),
])
def test_activity_file_iait_links(server_url, browser, link_text, url):
browser.get(server_url)
link = browser.find_elements_by_link_text(link_text)[0]
href = link.get_attribute("href")
assert url in href
@pytest.mark.parametrize(('link_text', 'url'), [
('xlsx', 'https://docs.google.com/spreadsheets/d/1MXjepDgfzKw0ULUWzKmXVS0Al6rMhMHlgN-ZF6hLc70/export?format=xlsx'),
('convert to spreadsheet', '?source_url=https://raw.githubusercontent.com/OpenDataServices/iati-sample-data/master/IATI-CoVE-sample-organisation-standard.xml?raw=true'),
('xml', 'https://github.com/OpenDataServices/iati-sample-data/blob/master/IATI-CoVE-sample-organisation-standard.xml'),
('convert to xml', '?source_url=https://docs.google.com/spreadsheets/d/1MXjepDgfzKw0ULUWzKmXVS0Al6rMhMHlgN-ZF6hLc70/export?format=xlsx'),
('google doc', 'https://docs.google.com/spreadsheets/d/1MXjepDgfzKw0ULUWzKmXVS0Al6rMhMHlgN-ZF6hLc70/edit?usp=sharing')
])
def test_organisation_file_iait_links(server_url, browser, link_text, url):
browser.get(server_url)
link = browser.find_elements_by_link_text(link_text)[1]
href = link.get_attribute("href")
assert url in href
def test_common_index_elements(server_url, browser):
browser.get(server_url)
browser.find_element_by_css_selector('#more-information .panel-title').click()
time.sleep(0.5)
assert 'What happens to the data I provide to this site?' in browser.find_element_by_tag_name('body').text
assert 'Why do you delete data after seven days?' in browser.find_element_by_tag_name('body').text
assert 'Why provide converted versions?' in browser.find_element_by_tag_name('body').text
@pytest.mark.parametrize(('source_filename', 'expected_text', 'conversion_successful'), [
('example.xml', ['Valid against Schema'], False),
('basic_iati_unordered_valid.xlsx', ['Valid against Schema'], True),
('basic_iati_unordered_invalid_iso_dates.xlsx', ['Invalid against Schema', 'Path: iati-activity/0/activity-date/@iso-date Line: 17', 'Path: iati-activity/1/activity-date/@iso-date Line: 54'], True),
('basic_iati_org_valid.xlsx', ['Valid against Schema'], True),
('bad.xml', ['We think you tried to upload a XML file'], False),
('bad_spaces.csv', ['Converted to XML 2 Errors'], True),
('basic_iati_ruleset_errors.xml', ['Invalid against Schema 13 Errors', '20140101',
'\'budget\': Missing child element(s), expected is value',
'Ruleset Errors 17 Errors',
'Start date (2010-01-01) must be before end date (2009-01-01)',
'Start dates must be chronologically before end dates',
'Percentages must sum to 100%',
'Elements must use a valid format',
'Actual dates must be in the past',
'Elements are mandatory',
'Sector must be specified'], False),
# We should not server error when there's fields not in the schema
('not_iati.csv', ['Data Supplied', 'Invalid against Schema'], True),
('namespace_good.xlsx', ['Converted to XML', 'Invalid against Schema', '2 Errors'], True),
('namespace_bad.xlsx', ['Converted to XML', 'Invalid against Schema', "'iati-activity', attribute 'test2': The attribute 'test2' is not allowed.", '3 Errors'], True),
])
def test_explore_iati_url_input(server_url, browser, httpserver, source_filename, expected_text, conversion_successful):
with open(os.path.join('cove_iati', 'fixtures', source_filename), 'rb') as fp:
httpserver.serve_content(fp.read())
if 'CUSTOM_SERVER_URL' in os.environ:
# Use urls pointing to GitHub if we have a custom (probably non local) server URL
source_url = 'https://raw.githubusercontent.com/OpenDataServices/cove/live/cove_iati/fixtures/' + source_filename
else:
source_url = httpserver.url + '/' + source_filename
browser.get(server_url)
browser.find_element_by_partial_link_text('Link').click()
time.sleep(0.5)
browser.find_element_by_id('id_source_url').send_keys(source_url)
browser.find_element_by_css_selector("#fetchURL > div.form-group > button.btn.btn-primary").click()
data_url = browser.current_url
# Click and un-collapse all explore sections
all_sections = browser.find_elements_by_class_name('panel-heading')
for section in all_sections:
if section.get_attribute('data-toggle') == "collapse" and section.get_attribute('aria-expanded') != 'true':
browser.execute_script("arguments[0].scrollIntoView();", section)
section.click()
time.sleep(0.5)
# Do the assertions
check_url_input_result_page(server_url, browser, httpserver, source_filename, expected_text, conversion_successful)
#refresh page to now check if tests still work after caching some data
browser.get(data_url)
# Expand all sections with the expand all button this time
try:
browser.find_element_by_link_text('Expand all').click()
time.sleep(0.5)
except NoSuchElementException:
pass
# Do the assertions again
check_url_input_result_page(server_url, browser, httpserver, source_filename, expected_text, conversion_successful)
def check_url_input_result_page(server_url, browser, httpserver, source_filename, expected_text, conversion_successful):
body_text = browser.find_element_by_tag_name('body').text
if isinstance(expected_text, str):
expected_text = [expected_text]
for text in expected_text:
assert text in body_text
if conversion_successful:
assert 'Converted to XML' in body_text
if source_filename == 'namespace_good.xlsx':
converted_file = browser.find_element_by_link_text("XML (Converted from Original)").get_attribute("href")
assert requests.get(converted_file).text == '''<?xml version='1.0' encoding='utf-8'?>
<iati-activities>
<!--Data generated by IATI CoVE. Built by Open Data Services Co-operative: http://iati.cove.opendataservices.coop/-->
<iati-activity xmlns:myns="http://example.org" myns:test2="3">
<myns:test>1</myns:test>
<test2>2</test2>
</iati-activity>
</iati-activities>
'''
if source_filename == 'basic_iati_org_valid.xlsx':
converted_file = browser.find_element_by_link_text("XML (Converted from Original)").get_attribute("href")
assert requests.get(converted_file).text == '''<?xml version='1.0' encoding='utf-8'?>
<iati-organisations version="2.03">
<!--Data generated by IATI CoVE. Built by Open Data Services Co-operative: http://iati.cove.opendataservices.coop/-->
<iati-organisation default-currency="EUR" last-updated-datetime="2014-09-10T07:15:37Z" xml:lang="en">
<organisation-identifier>AA-AAA-123456789</organisation-identifier>
<name>
<narrative>Organisation name</narrative>
</name>
<reporting-org ref="AA-AAA-123456789" type="40">
<narrative>Organisation name</narrative>
</reporting-org>
<document-link format="application/vnd.oasis.opendocument.text" url="http://www.example.org/docs/report_en.odt">
<title>
<narrative>Annual Report 2013</narrative>
</title>
<category code="B01"/>
<language code="en"/>
<document-date iso-date="2014-02-05"/>
<recipient-country code="AF"/>
</document-link>
<document-link format="application/vnd.oasis.opendocument.text" url="http://www.example.org/docs/report_fr.odt">
<title>
<narrative xml:lang="fr">Rapport annuel 2013</narrative>
</title>
<category code="B01"/>
<language code="fr"/>
<document-date iso-date="2014-02-05"/>
<recipient-country code="AF"/>
</document-link>
</iati-organisation>
</iati-organisations>
'''
def test_rulesets_table_toggle(server_url, browser, httpserver):
with open(os.path.join('cove_iati', 'fixtures', 'basic_iati_ruleset_errors.xml'), 'rb') as fp:
httpserver.serve_content(fp.read())
if 'CUSTOM_SERVER_URL' in os.environ:
# Use urls pointing to GitHub if we have a custom (probably non local) server URL
source_url = ('https://raw.githubusercontent.com/OpenDataServices/cove/'
'live/cove_iati/fixtures/basic_iati_ruleset_errors.xml')
else:
source_url = httpserver.url + '/basic_iati_ruleset_errors.xml'
browser.get(server_url)
browser.find_element_by_partial_link_text('Link').click()
time.sleep(0.5)
browser.find_element_by_id('id_source_url').send_keys(source_url)
browser.find_element_by_css_selector('#fetchURL > div.form-group > button.btn.btn-primary').click()
# Click and un-collapse all explore sections
all_sections = browser.find_elements_by_class_name('panel-heading')
for section in all_sections:
if section.get_attribute('data-toggle') == 'collapse':
if section.get_attribute('aria-expanded') != 'true':
browser.execute_script('arguments[0].scrollIntoView();', section)
section.click()
time.sleep(0.5)
toggle_button = browser.find_element_by_name('ruleset-table-toggle')
table_header = browser.find_element_by_css_selector('table#ruleset-by-rule thead tr')
header_html = ''.join(table_header.get_attribute('innerHTML').strip().split())
assert toggle_button.text == 'See same results by activity'
assert browser.find_element_by_id('ruleset-by-rule').is_displayed()
assert not browser.find_element_by_id('ruleset-by-activity').is_displayed()
assert header_html == '<th>Ruleset</th><th>Rule</th><th>Activity</th><th>Explanation</th><th>Path</th>'
toggle_button.click()
time.sleep(0.5)
toggle_button = browser.find_element_by_name('ruleset-table-toggle')
table_header = browser.find_element_by_css_selector('table#ruleset-by-activity thead tr')
header_html = ''.join(table_header.get_attribute('innerHTML').strip().split())
assert toggle_button.text == 'See same results by ruleset'
assert browser.find_element_by_id('ruleset-by-activity').is_displayed()
assert not browser.find_element_by_id('ruleset-by-rule').is_displayed()
assert header_html == '<th>Activity</th><th>Ruleset</th><th>Rule</th><th>Explanation</th><th>Path</th>'