summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2018-12-02 11:36:16 +0100
committerLars-Dominik Braun <lars@6xq.net>2018-12-02 11:38:58 +0100
commite39e4f9ecb1998d379330b1bc08a9818e9202323 (patch)
treeb4a86750fd78dbf1babe9cb4002b4c85caaea03f
parent5db26384556be4d7cee3ba93dfc6375c8d80b6ea (diff)
downloadcrocoite-e39e4f9ecb1998d379330b1bc08a9818e9202323.tar.gz
crocoite-e39e4f9ecb1998d379330b1bc08a9818e9202323.tar.bz2
crocoite-e39e4f9ecb1998d379330b1bc08a9818e9202323.zip
behavior: Improve click testing
Some pages require scrolling, so we need a SinglePageController. Also mark network-dependent tests with xfail, so they won’t affect the overall test result unless you know what you’re doing (--runxfail).
-rw-r--r--crocoite/data/click.yaml24
-rw-r--r--crocoite/test_behavior.py54
2 files changed, 56 insertions, 22 deletions
diff --git a/crocoite/data/click.yaml b/crocoite/data/click.yaml
index d9557eb..60db0c2 100644
--- a/crocoite/data/click.yaml
+++ b/crocoite/data/click.yaml
@@ -1,19 +1,24 @@
-# configuration for behavior.py:Click
+# Configuration for behavior.py:Click
+# Example URLs are random. Believe me.
match: ^www\.facebook\.com$
selector:
- description: show more comments
selector: a.UFIPagerLink[role=button]
+ urls: ["https://www.facebook.com/tagesschau"]
- description: show nested comments
selector: a.UFICommentLink[role=button]
- description: initially show comments below a single post/video, i.e. /user/post/123
selector: form.commentable_item a[data-comment-prelude-ref=action_link_bling][rel=ignore]
+ urls: ["https://www.facebook.com/tagesschau/posts/10157061068659407"]
- description: close the “register now” nag screen. for better screen shots
selector: a#expanding_cta_close_button[role=button]
+ urls: ["https://www.facebook.com/tagesschau"]
---
match: ^twitter\.com$
selector:
- description: expand threads
selector: a.ThreadedConversation-moreRepliesLink
+ urls: ["https://twitter.com/realDonaldTrump/status/1068826073775964160"]
- description: show hidden profiles
selector: button.ProfileWarningTimeline-button
- description: show hidden/sensitive media
@@ -30,6 +35,8 @@ selector:
- description: show more comments, reddit’s javascript ignores events if too frequent
selector: span.morecomments a
throttle: 500
+ # disabled: No idea why it is not working. The selector is fine.
+ #urls: ["https://www.reddit.com/r/funny/comments/a21rxz/well_this_was_a_highlight_of_my_day/"]
---
match: ^www\.instagram\.com$
selector:
@@ -42,26 +49,33 @@ match: ^www\.youtube\.com$
selector:
- description: expand comment thread
selector: ytd-comment-thread-renderer div.more-button
+ urls: ["https://www.youtube.com/watch?v=udtFqQuBFSc"]
---
match: ^www\.patreon\.com$
selector:
- description: load more content
- selector: div[display=flex] div[display=block] button[color=gray][type=button]
- multi: True
+ # I’ve been trying to avoid these generated css class selectors *so* hard,
+ # but it’s just not possible on this one.
+ selector: div.sc-bZQynM.fSJOpK button
+ urls: ["https://www.patreon.com/nkjemisin"]
- description: load more comments
- selector: div.stackable[display=block] > div > div > a[color=dark][target=_self]
+ selector: div[display=flex] div[display=block] a[color="dark"][role="button"][tabindex="0"]
+ urls: ["https://www.patreon.com/posts/what-im-on-22124040"]
- description: load more replies
selector: div > a[scale="0"][color=blue][size="1"]
---
match: ^(www\.)?gab\.ai$
selector:
- - description: post comments
+ - description: more replies
selector: post-detail post-comment .post-comment__replies__count a
+ urls: ["https://gab.ai/gab/posts/40014689"]
- description: more comments
selector: post-detail .post-comment-list__loading a
+ urls: ["https://gab.ai/gab/posts/41804462"]
- description: more posts
selector: post-list a.post-list__load-more
multi: True
+ urls: ["https://gab.ai/gab"]
---
match: ^(www\.)?github\.com$
selector:
diff --git a/crocoite/test_behavior.py b/crocoite/test_behavior.py
index 03e151c..280b35b 100644
--- a/crocoite/test_behavior.py
+++ b/crocoite/test_behavior.py
@@ -20,12 +20,14 @@
import asyncio, os, yaml, re
from urllib.parse import urlparse
+from functools import partial
import pytest
import pkg_resources
-from .browser import Item, SiteLoader, VarChangeEvent
-from .logger import Logger, Consumer
+from .logger import Logger
from .devtools import Process
+from .behavior import Scroll, Behavior
+from .controller import SinglePageController
with pkg_resources.resource_stream (__name__, os.path.join ('data', 'click.yaml')) as fd:
sites = list (yaml.load_all (fd))
@@ -35,27 +37,28 @@ for o in sites:
for u in s.get ('urls', []):
clickParam.append ((u, s['selector']))
-@pytest.mark.parametrize("url,selector", clickParam)
-@pytest.mark.asyncio
-async def test_click_selectors (url, selector):
+class ClickTester (Behavior):
"""
- Make sure the CSS selector exists on an example url
+ Test adapter checking a given selector exists after loading the page
"""
- logger = Logger ()
- async with Process () as browser, SiteLoader (browser, url, logger) as l:
- tab = l.tab
- await l.start ()
- # XXX: not sure why this is needed, must be a bug.
- await asyncio.sleep (0.5)
- if not l.idle.get ():
- await l.idle.wait ()
+
+ __slots__ = ('selector', )
+
+ name = 'testclick'
+
+ def __init__ (self, loader, logger, selector):
+ super ().__init__ (loader, logger)
+ self.selector = selector
+
+ async def onfinish (self):
+ tab = self.loader.tab
results = await tab.DOM.getDocument ()
rootNode = results['root']['nodeId']
- results = await tab.DOM.querySelectorAll (nodeId=rootNode, selector=selector)
- assert results['nodeIds'], selector
+ results = await tab.DOM.querySelectorAll (nodeId=rootNode, selector=self.selector)
+ assert results['nodeIds'], self.selector
# XXX: this is not true for every element we click. Github uses <button
- # type=submit> and <form> without an event listener
+ # type=submit> and <form> without an event listener on the <button>
# # verify that an event listener exists
# for nid in results['nodeIds']:
# obj = (await tab.DOM.resolveNode (nodeId=nid))['object']
@@ -63,6 +66,23 @@ async def test_click_selectors (url, selector):
# listeners = (await tab.DOMDebugger.getEventListeners (objectId=obj['objectId']))['listeners']
# assert any (map (lambda x: x['type'] == 'click', listeners)), listeners
+ return
+ yield
+
+@pytest.mark.parametrize("url,selector", clickParam)
+@pytest.mark.asyncio
+@pytest.mark.xfail(reason='depends on network access')
+async def test_click_selectors (url, selector):
+ """
+ Make sure the CSS selector exists on an example url
+ """
+ logger = Logger ()
+ # Some selectors are loaded dynamically and require scrolling
+ controller = SinglePageController (url=url, logger=logger,
+ service=Process (),
+ behavior=[Scroll, partial(ClickTester, selector=selector)])
+ await controller.run ()
+
matchParam = []
for o in sites:
for s in o['selector']: