diff options
-rw-r--r-- | crocoite/data/click.yaml | 24 | ||||
-rw-r--r-- | crocoite/test_behavior.py | 54 |
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']: |