|
@@ -921,6 +921,15 @@ class OrganizationReplayIndexTest(APITestCase, ReplaysSnubaTestCase):
|
|
|
"replay_click.testid:1",
|
|
|
"replay_click.textContent:Hello",
|
|
|
"replay_click.title:MyTitle",
|
|
|
+ "replay_click.selector:div#myid",
|
|
|
+ "replay_click.selector:div[alt=Alt]",
|
|
|
+ "replay_click.selector:div[title=MyTitle]",
|
|
|
+ "replay_click.selector:div[data-testid='1']",
|
|
|
+ "replay_click.selector:div[role=button]",
|
|
|
+ "replay_click.selector:div#myid.class1.class2",
|
|
|
+ # Single quotes around attribute value.
|
|
|
+ "replay_click.selector:div[role='button']",
|
|
|
+ "replay_click.selector:div#myid.class1.class2[role=button][aria-label='AriaLabel']",
|
|
|
]
|
|
|
for query in queries:
|
|
|
response = self.client.get(self.url + f"?field=id&query={query}")
|
|
@@ -938,9 +947,85 @@ class OrganizationReplayIndexTest(APITestCase, ReplaysSnubaTestCase):
|
|
|
"replay_click.testid:2",
|
|
|
"replay_click.textContent:World",
|
|
|
"replay_click.title:NotMyTitle",
|
|
|
+ "!replay_click.selector:div#myid",
|
|
|
+ "replay_click.selector:div#notmyid",
|
|
|
+ # Assert all classes must match.
|
|
|
+ "replay_click.selector:div#myid.class1.class2.class3",
|
|
|
+ # Invalid selectors return no rows.
|
|
|
+ "replay_click.selector:$#%^#%",
|
|
|
+ # Integer type role values are not allowed and must be wrapped in single quotes.
|
|
|
+ "replay_click.selector:div[title=1]",
|
|
|
]
|
|
|
for query in queries:
|
|
|
response = self.client.get(self.url + f"?query={query}")
|
|
|
assert response.status_code == 200, query
|
|
|
response_data = response.json()
|
|
|
assert len(response_data["data"]) == 0, query
|
|
|
+
|
|
|
+ def test_get_replays_filter_clicks_nested_selector(self):
|
|
|
+ """Test replays do not support nested selectors."""
|
|
|
+ project = self.create_project(teams=[self.team])
|
|
|
+ self.store_replays(mock_replay(datetime.datetime.now(), project.id, uuid.uuid4().hex))
|
|
|
+
|
|
|
+ with self.feature(REPLAYS_FEATURES):
|
|
|
+ queries = [
|
|
|
+ 'replay_click.selector:"div button"',
|
|
|
+ 'replay_click.selector:"div + button"',
|
|
|
+ 'replay_click.selector:"div ~ button"',
|
|
|
+ 'replay_click.selector:"div > button"',
|
|
|
+ ]
|
|
|
+ for query in queries:
|
|
|
+ response = self.client.get(self.url + f"?field=id&query={query}")
|
|
|
+ assert response.status_code == 400
|
|
|
+ assert response.content == b'{"detail":"Nested selectors are not supported."}'
|
|
|
+
|
|
|
+ def test_get_replays_filter_clicks_pseudo_element(self):
|
|
|
+ """Assert replays only supports a subset of selector syntax."""
|
|
|
+ project = self.create_project(teams=[self.team])
|
|
|
+ self.store_replays(mock_replay(datetime.datetime.now(), project.id, uuid.uuid4().hex))
|
|
|
+
|
|
|
+ with self.feature(REPLAYS_FEATURES):
|
|
|
+ queries = [
|
|
|
+ "replay_click.selector:a::visited",
|
|
|
+ ]
|
|
|
+ for query in queries:
|
|
|
+ response = self.client.get(self.url + f"?field=id&query={query}")
|
|
|
+ assert response.status_code == 400, query
|
|
|
+ assert response.content == b'{"detail":"Pseudo-elements are not supported."}', query
|
|
|
+
|
|
|
+ def test_get_replays_filter_clicks_unsupported_selector(self):
|
|
|
+ """Assert replays only supports a subset of selector syntax."""
|
|
|
+ project = self.create_project(teams=[self.team])
|
|
|
+ self.store_replays(mock_replay(datetime.datetime.now(), project.id, uuid.uuid4().hex))
|
|
|
+
|
|
|
+ with self.feature(REPLAYS_FEATURES):
|
|
|
+ queries = [
|
|
|
+ "replay_click.selector:div:is(2)",
|
|
|
+ "replay_click.selector:p:active",
|
|
|
+ ]
|
|
|
+ for query in queries:
|
|
|
+ response = self.client.get(self.url + f"?field=id&query={query}")
|
|
|
+ assert response.status_code == 400, query
|
|
|
+ assert (
|
|
|
+ response.content
|
|
|
+ == b'{"detail":"Only attribute, class, id, and tag name selectors are supported."}'
|
|
|
+ ), query
|
|
|
+
|
|
|
+ def test_get_replays_filter_clicks_unsupported_operators(self):
|
|
|
+ """Assert replays only supports a subset of selector syntax."""
|
|
|
+ project = self.create_project(teams=[self.team])
|
|
|
+ self.store_replays(mock_replay(datetime.datetime.now(), project.id, uuid.uuid4().hex))
|
|
|
+
|
|
|
+ with self.feature(REPLAYS_FEATURES):
|
|
|
+ queries = [
|
|
|
+ 'replay_click.selector:"[aria-label~=button]"',
|
|
|
+ 'replay_click.selector:"[aria-label|=button]"',
|
|
|
+ 'replay_click.selector:"[aria-label^=button]"',
|
|
|
+ 'replay_click.selector:"[aria-label$=button]"',
|
|
|
+ ]
|
|
|
+ for query in queries:
|
|
|
+ response = self.client.get(self.url + f"?field=id&query={query}")
|
|
|
+ assert response.status_code == 400, query
|
|
|
+ assert (
|
|
|
+ response.content == b'{"detail":"Only the \'=\' operator is supported."}'
|
|
|
+ ), query
|