diff --git a/tests/integration/data/click_element.html b/tests/integration/data/click_element.html
new file mode 100644
index 000000000..9e5ce5bb5
--- /dev/null
+++ b/tests/integration/data/click_element.html
@@ -0,0 +1,11 @@
+
+
+ quteprocess.click_element test
+
+
+ Test Element
+ "Don't", he shouted
+ Duplicate
+ Duplicate
+
+
diff --git a/tests/integration/test_quteprocess.py b/tests/integration/test_quteprocess.py
index 872ec73de..4cf537a71 100644
--- a/tests/integration/test_quteprocess.py
+++ b/tests/integration/test_quteprocess.py
@@ -158,3 +158,39 @@ def test_log_line_parse(data, attrs):
def test_log_line_no_match():
with pytest.raises(testprocess.InvalidLine):
quteprocess.LogLine("Hello World!")
+
+
+class TestClickElement:
+
+ @pytest.fixture(autouse=True)
+ def open_page(self, quteproc):
+ quteproc.open_path('data/click_element.html')
+ quteproc.wait_for_load_finished('data/click_element.html')
+
+ def test_click_element(self, quteproc):
+ quteproc.click_element('Test Element')
+ quteproc.wait_for_js('click_element clicked')
+
+ def test_click_special_chars(self, quteproc):
+ quteproc.click_element('"Don\'t", he shouted')
+ quteproc.wait_for_js('click_element special chars')
+
+ def test_duplicate(self, quteproc):
+ with pytest.raises(ValueError) as excinfo:
+ quteproc.click_element('Duplicate')
+ assert 'not unique' in str(excinfo.value)
+
+ def test_nonexistent(self, quteproc):
+ with pytest.raises(ValueError) as excinfo:
+ quteproc.click_element('no element exists with this text')
+ assert 'No element' in str(excinfo.value)
+
+
+@pytest.mark.parametrize('string, expected', [
+ ('Test', "'Test'"),
+ ("Don't", '"Don\'t"'),
+ # This is some serious string escaping madness
+ ('"Don\'t", he said', "concat('\"', 'Don', \"'\", 't', '\"', ', he said')"),
+])
+def test_xpath_escape(string, expected):
+ assert quteprocess._xpath_escape(string) == expected