2016-12-18 20:42:45 +03:00
|
|
|
import pytest
|
2015-12-22 00:21:15 +03:00
|
|
|
import os
|
|
|
|
import utilities
|
2015-12-30 00:43:17 +03:00
|
|
|
import expected
|
2016-05-05 18:38:56 +03:00
|
|
|
from openwpmtest import OpenWPMTest
|
|
|
|
from ..automation import TaskManager
|
2016-12-15 02:03:25 +03:00
|
|
|
from datetime import datetime
|
2016-04-12 03:47:05 +03:00
|
|
|
# TODO: add test for setter instrumentation
|
2015-12-22 00:21:15 +03:00
|
|
|
|
|
|
|
|
2016-04-12 03:47:05 +03:00
|
|
|
class TestExtension(OpenWPMTest):
|
2015-12-22 00:21:15 +03:00
|
|
|
|
2016-12-18 20:42:45 +03:00
|
|
|
def get_config(self, data_dir=""):
|
|
|
|
manager_params, browser_params = self.get_test_config(data_dir)
|
2016-11-22 03:08:36 +03:00
|
|
|
browser_params[0]['js_instrument'] = True
|
2015-12-22 00:21:15 +03:00
|
|
|
return manager_params, browser_params
|
|
|
|
|
2016-12-18 20:42:45 +03:00
|
|
|
def test_property_enumeration(self):
|
2016-04-12 03:47:05 +03:00
|
|
|
test_url = utilities.BASE_TEST_URL + '/property_enumeration.html'
|
2016-12-18 20:42:45 +03:00
|
|
|
db = self.visit(test_url)
|
2016-04-12 03:47:05 +03:00
|
|
|
rows = utilities.query_db(db,
|
|
|
|
"SELECT script_url, symbol FROM javascript")
|
2015-12-22 00:21:15 +03:00
|
|
|
observed_symbols = set()
|
2016-04-12 03:47:05 +03:00
|
|
|
for script_url, symbol in rows:
|
|
|
|
assert script_url == test_url
|
2015-12-22 00:21:15 +03:00
|
|
|
observed_symbols.add(symbol)
|
2015-12-30 00:43:17 +03:00
|
|
|
assert expected.properties == observed_symbols
|
|
|
|
|
2016-12-18 20:42:45 +03:00
|
|
|
def test_canvas_fingerprinting(self):
|
|
|
|
db = self.visit('/canvas_fingerprinting.html')
|
2015-12-30 00:43:17 +03:00
|
|
|
# Check that all calls and methods are recorded
|
2016-04-12 03:47:05 +03:00
|
|
|
rows = utilities.get_javascript_entries(db)
|
2015-12-30 00:43:17 +03:00
|
|
|
observed_rows = set()
|
2016-04-12 03:47:05 +03:00
|
|
|
for item in rows:
|
2015-12-30 00:43:17 +03:00
|
|
|
observed_rows.add(item)
|
|
|
|
assert expected.canvas == observed_rows
|
2016-04-12 03:47:05 +03:00
|
|
|
|
2016-12-18 20:42:45 +03:00
|
|
|
def test_extension_gets_correct_visit_id(self):
|
|
|
|
manager_params, browser_params = self.get_config()
|
2016-05-05 18:38:56 +03:00
|
|
|
manager = TaskManager.TaskManager(manager_params, browser_params)
|
|
|
|
|
|
|
|
url_a = utilities.BASE_TEST_URL + '/simple_a.html'
|
|
|
|
url_b = utilities.BASE_TEST_URL + '/simple_b.html'
|
|
|
|
|
|
|
|
manager.get(url_a)
|
|
|
|
manager.get(url_b)
|
2016-12-05 20:32:55 +03:00
|
|
|
manager.close()
|
2016-05-05 18:38:56 +03:00
|
|
|
qry_res = utilities.query_db(manager_params['db'],
|
|
|
|
"SELECT visit_id, site_url FROM site_visits")
|
|
|
|
|
|
|
|
# Construct dict mapping site_url to visit_id
|
|
|
|
visit_ids = dict()
|
|
|
|
for row in qry_res:
|
|
|
|
visit_ids[row[1]] = row[0]
|
|
|
|
|
|
|
|
simple_a_visit_id = utilities.query_db(
|
|
|
|
manager_params['db'],
|
|
|
|
"SELECT visit_id FROM javascript WHERE "
|
|
|
|
"symbol=?", ("window.navigator.userAgent",))
|
|
|
|
|
|
|
|
simple_b_visit_id = utilities.query_db(
|
|
|
|
manager_params['db'],
|
|
|
|
"SELECT visit_id FROM javascript WHERE "
|
|
|
|
"symbol=?", ("window.navigator.platform",))
|
|
|
|
|
|
|
|
assert visit_ids[url_a] == simple_a_visit_id[0][0]
|
|
|
|
assert visit_ids[url_b] == simple_b_visit_id[0][0]
|
|
|
|
|
2016-04-12 03:47:05 +03:00
|
|
|
def check_webrtc_sdp_offer(self, sdp_str):
|
|
|
|
"""Make sure the SDP offer includes expected fields/strings.
|
|
|
|
|
|
|
|
SDP offer contains randomly generated strings (e.g. GUID). That's why
|
|
|
|
we don't expect a fixed string but only check the presence of certain
|
|
|
|
protocol fields.
|
|
|
|
"""
|
|
|
|
for expected_str in expected.webrtc_sdp_offer_strings:
|
|
|
|
assert expected_str in sdp_str
|
|
|
|
|
2016-12-18 20:42:45 +03:00
|
|
|
def test_webrtc_localip(self):
|
|
|
|
db = self.visit('/webrtc_localip.html')
|
2016-04-12 03:47:05 +03:00
|
|
|
# Check that all calls and methods are recorded
|
|
|
|
rows = utilities.get_javascript_entries(db)
|
|
|
|
observed_rows = set()
|
|
|
|
for item in rows:
|
|
|
|
if item[1] == "RTCPeerConnection.setLocalDescription":
|
|
|
|
assert item[2:5] == (u'call', u'', 0)
|
|
|
|
sdp_offer = item[5]
|
|
|
|
self.check_webrtc_sdp_offer(sdp_offer)
|
|
|
|
else:
|
|
|
|
observed_rows.add(item)
|
|
|
|
assert set(expected.webrtc_calls) == observed_rows
|
2016-09-12 18:18:22 +03:00
|
|
|
|
2016-10-04 22:23:11 +03:00
|
|
|
@pytest.mark.skipif("TRAVIS" in os.environ and os.environ["TRAVIS"] == "true", reason='Flaky on Travis CI')
|
2016-12-18 20:42:45 +03:00
|
|
|
def test_audio_fingerprinting(self):
|
|
|
|
db = self.visit('/audio_fingerprinting.html')
|
2016-09-12 18:18:22 +03:00
|
|
|
# Check that all calls and methods are recorded
|
|
|
|
rows = utilities.get_javascript_entries(db)
|
|
|
|
observed_symbols = set()
|
|
|
|
for item in rows:
|
|
|
|
observed_symbols.add(item[1])
|
|
|
|
assert expected.audio == observed_symbols
|
|
|
|
|
2016-12-18 20:42:45 +03:00
|
|
|
def test_js_call_stack(self):
|
|
|
|
db = self.visit('/js_call_stack.html')
|
2016-12-01 02:04:43 +03:00
|
|
|
# Check that all stack info are recorded
|
|
|
|
rows = utilities.get_javascript_entries(db, all_columns=True)
|
|
|
|
observed_rows = set()
|
|
|
|
for item in rows:
|
|
|
|
observed_rows.add(item[3:11])
|
|
|
|
assert set(expected.js_stack_calls) == observed_rows
|
|
|
|
|
2016-12-18 20:42:45 +03:00
|
|
|
def test_js_time_stamp(self):
|
2016-12-15 02:03:25 +03:00
|
|
|
# Check that timestamp is recorded correctly for the javascript table
|
|
|
|
MAX_TIMEDELTA = 30 # max time diff in seconds
|
2016-12-18 20:42:45 +03:00
|
|
|
db = self.visit('/canvas_fingerprinting.html')
|
2016-12-15 02:03:25 +03:00
|
|
|
utc_now = datetime.utcnow() # OpenWPM stores timestamp in UTC time
|
|
|
|
rows = utilities.get_javascript_entries(db, all_columns=True)
|
|
|
|
assert len(rows) # make sure we have some JS events captured
|
|
|
|
for row in rows:
|
|
|
|
js_time = datetime.strptime(row[14], "%Y-%m-%dT%H:%M:%S.%fZ")
|
|
|
|
# compare UTC now and the timestamp recorded at the visit
|
|
|
|
assert (utc_now - js_time).seconds < MAX_TIMEDELTA
|
|
|
|
assert not utilities.any_command_failed(db)
|
2016-12-22 01:05:23 +03:00
|
|
|
|
|
|
|
def test_document_cookie_instrumentation(self):
|
|
|
|
db = self.visit(utilities.BASE_TEST_URL + "/js_cookie.html")
|
|
|
|
rows = utilities.get_javascript_entries(db, all_columns=True)
|
|
|
|
# [3:12] exclude id and empty columns
|
|
|
|
captured_cookie_calls = set([row[3:12] for row in rows])
|
|
|
|
assert captured_cookie_calls == expected.document_cookie_read_write
|