forked from zedeus/nitter
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
199 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
nitter | ||
*.html | ||
*.db | ||
*.db | ||
tests/__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
from seleniumbase import BaseCase | ||
|
||
|
||
class Tweet(object): | ||
def __init__(self, tweet=''): | ||
namerow = tweet + 'div.media-heading > div > .fullname-and-username > ' | ||
self.fullname = namerow + '.fullname' | ||
self.username = namerow + '.username' | ||
self.date = tweet + 'div.media-heading > div > .heading-right' | ||
self.text = tweet + '.status-content-wrapper > .status-content.media-body' | ||
|
||
|
||
class Profile(object): | ||
fullname = '.profile-card-fullname' | ||
username = '.profile-card-username' | ||
bio = '.profile-bio' | ||
protected = '.protected-icon' | ||
verified = '.verified-icon' | ||
|
||
|
||
class BaseTestCase(BaseCase): | ||
def setUp(self): | ||
super(BaseTestCase, self).setUp() | ||
|
||
def tearDown(self): | ||
super(BaseTestCase, self).tearDown() | ||
|
||
def open_nitter(self, page=''): | ||
self.open(f'http://localhost:5000/{page}') | ||
|
||
def search_username(self, username): | ||
self.open_nitter() | ||
self.update_text('input', username) | ||
self.submit('form') | ||
|
||
|
||
def get_timeline_tweet(num=1): | ||
return Tweet(f'#tweets > div:nth-child({num}) > div > div ') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from base import BaseTestCase, Profile | ||
|
||
|
||
class TestProfile(BaseTestCase): | ||
def test_data(self): | ||
self.open_nitter('mobile_test') | ||
self.assert_exact_text('Test account', Profile.fullname) | ||
self.assert_exact_text('@mobile_test', Profile.username) | ||
self.assert_exact_text('Test Account. test test Testing username with @mobile_test_2 and a #hashtag', | ||
Profile.bio) | ||
|
||
self.open_nitter('mobile_test_2') | ||
self.assert_exact_text('mobile test 2', Profile.fullname) | ||
self.assert_exact_text('@mobile_test_2', Profile.username) | ||
self.assert_element_not_visible(Profile.bio) | ||
|
||
def test_verified(self): | ||
self.open_nitter('jack') | ||
self.assert_element_visible(Profile.verified) | ||
|
||
self.open_nitter('elonmusk') | ||
self.assert_element_visible(Profile.verified) | ||
|
||
def test_protected(self): | ||
self.open_nitter('mobile_test_7') | ||
self.assert_element_visible(Profile.protected) | ||
self.assert_exact_text('mobile test 7', Profile.fullname) | ||
self.assert_exact_text('@mobile_test_7', Profile.username) | ||
self.assert_text('Tweets are protected') | ||
|
||
self.open_nitter('poop') | ||
self.assert_element_visible(Profile.protected) | ||
self.assert_exact_text('Randy', Profile.fullname) | ||
self.assert_exact_text('@Poop', Profile.username) | ||
self.assert_text('Social media fanatic.', Profile.bio) | ||
self.assert_text('Tweets are protected') | ||
|
||
def test_invalid_username(self): | ||
for p in ['test', 'thisprofiledoesntexist', '%']: | ||
self.open_nitter(p) | ||
self.assert_text(f'User "{p}" not found') | ||
|
||
def test_suspended(self): | ||
# TODO: detect suspended | ||
self.open_nitter('test') | ||
self.assert_text(f'User "test" not found') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from base import BaseTestCase | ||
|
||
|
||
class TestSearch(BaseTestCase): | ||
def test_username_search(self): | ||
self.search_username('mobile_test') | ||
self.assert_text('@mobile_test') | ||
|
||
self.search_username('mobile_test_2') | ||
self.assert_text('@mobile_test_2') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
from base import BaseTestCase, Tweet, get_timeline_tweet | ||
|
||
# image = tweet + 'div.attachments.media-body > div > div > a > div > img' | ||
# self.assert_true(self.get_image_url(image).split('/')[0] == 'http') | ||
class TweetInfo(): | ||
def __init__(self, index, fullname, username, date, text): | ||
self.index = index | ||
self.fullname = fullname | ||
self.username = username | ||
self.date = date | ||
self.text = text | ||
|
||
timeline_tweets = [ | ||
TweetInfo(1, 'Test account', 'mobile_test', '10 Aug 2016', | ||
'.'), | ||
|
||
TweetInfo(3, 'Test account', 'mobile_test', '3 Mar 2016', | ||
'LIVE on #Periscope pscp.tv/w/aadiTzF6dkVOTXZSbX…'), | ||
|
||
TweetInfo(6, 'mobile test 2', 'mobile_test_2', '1 Oct 2014', | ||
'Testing. One two three four. Test.') | ||
] | ||
|
||
status_tweets = [ | ||
TweetInfo(20, 'jack 🌍🌏🌎', 'jack', '21 Mar 2006', | ||
'just setting up my twttr'), | ||
|
||
TweetInfo(134849778302464000, 'The Twoffice', 'TheTwoffice', '10 Nov 2011', | ||
'test'), | ||
|
||
TweetInfo(105685475985080322, 'The Twoffice', 'TheTwoffice', '22 Aug 2011', | ||
'regular tweet'), | ||
|
||
TweetInfo(572593440719912960, 'Test account', 'mobile_test', '2 Mar 2015', | ||
'testing test') | ||
] | ||
|
||
invalid_tweets = [ | ||
'mobile_test/status/120938109238', | ||
'TheTwoffice/status/8931928312' | ||
] | ||
|
||
multiline_tweets = [ | ||
TweetInfo(1142904127594401797, '', 'hot_pengu', '', | ||
""" | ||
New tileset, dust effects, background. The 'sea' has per-line parallax and wavey fx which we think is really cool even tho u didn't notice 🐶. code: | ||
@exelotl | ||
#pixelart #gbadev #gba #indiedev"""), | ||
|
||
TweetInfo(400897186990284800, '', 'mobile_test_3', '', | ||
""" | ||
♔ | ||
KEEP | ||
CALM | ||
AND | ||
CLICHÉ | ||
ON""") | ||
] | ||
|
||
class TestTweet(BaseTestCase): | ||
def test_timeline(self): | ||
for info in timeline_tweets: | ||
self.open_nitter(f'{info.username}') | ||
tweet = get_timeline_tweet(info.index) | ||
self.assert_exact_text(info.fullname, tweet.fullname) | ||
self.assert_exact_text('@' + info.username, tweet.username) | ||
self.assert_exact_text(info.date, tweet.date) | ||
self.assert_text(info.text, tweet.text) | ||
|
||
def test_status(self): | ||
tweet = Tweet() | ||
for info in status_tweets: | ||
self.open_nitter(f'{info.username}/status/{info.index}') | ||
self.assert_exact_text(info.fullname, tweet.fullname) | ||
self.assert_exact_text('@' + info.username, tweet.username) | ||
self.assert_exact_text(info.date, tweet.date) | ||
self.assert_text(info.text, tweet.text) | ||
|
||
def test_multiline_formatting(self): | ||
for info in multiline_tweets: | ||
self.open_nitter(f'{info.username}/status/{info.index}') | ||
self.assert_text(info.text.strip('\n'), '.main-tweet') | ||
|
||
def test_emojis(self): | ||
self.open_nitter('Tesla/status/1134850442511257600') | ||
self.assert_text('🌈❤️🧡💛💚💙💜', '.main-tweet') | ||
|
||
def test_links(self): | ||
self.open_nitter('nim_lang/status/1110499584852353024') | ||
self.assert_text('nim-lang.org/araq/ownedrefs.…', '.main-tweet') | ||
self.assert_text('news.ycombinator.com/item?id…', '.main-tweet') | ||
self.assert_text('old.reddit.com/r/programming…', '.main-tweet') | ||
|
||
self.open_nitter('nim_lang/status/1125887775151140864') | ||
self.assert_text('en.wikipedia.org/wiki/Nim_(p…)', '.main-tweet') | ||
|
||
self.open_nitter('hiankun_taioan/status/1086916335215341570') | ||
self.assert_text('(hackernoon.com/interview-wit…)', '.main-tweet') | ||
|
||
def test_invalid_id(self): | ||
for tweet in invalid_tweets: | ||
self.open_nitter(tweet) | ||
self.assert_text('Tweet not found', '.error-panel') |