Files
app/tests/test_persimmons_ux.py
T

79 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Packaged UX invariants; real computed styles/flows in the browser check."""
import hashlib
import json
from pathlib import Path
import struct
import unittest
import zipfile
ROOT = Path(__file__).resolve().parents[1]
class UxTests(unittest.TestCase):
def test_packaged_icons_and_pinned_identity(self):
import base64
with zipfile.ZipFile(ROOT / 'persimmons/web/extension.zip') as archive:
manifest = json.loads(archive.read('persimmons-extension/manifest.json'))
digest = hashlib.sha256(base64.b64decode(manifest['key'])).hexdigest()[:32]
self.assertEqual(''.join(chr(ord('a') + int(c, 16)) for c in digest),
'kiolgjoohhgdohcafgelhikpgkbmckbg')
self.assertEqual(
manifest['version'],
json.loads((ROOT / 'persimmons-extension/manifest.json').read_text())['version'],
)
for size in (16, 32, 48, 128):
name = manifest['icons'][str(size)]
self.assertEqual(manifest['action']['default_icon'][str(size)], name)
raw = archive.read('persimmons-extension/' + name)
self.assertEqual(raw[:8], b'\x89PNG\r\n\x1a\n')
self.assertEqual(struct.unpack('>II', raw[16:24]), (size, size))
self.assertEqual(raw, (ROOT / 'persimmons-extension' / name).read_bytes())
self.assertFalse(any('/tests/' in name for name in archive.namelist()))
self.assertEqual(manifest['externally_connectable'], {'matches': ['https://persimmons.app/*']})
self.assertNotIn('content_scripts', manifest)
self.assertEqual(manifest['permissions'], ['activeTab', 'scripting', 'storage'])
popup = archive.read('persimmons-extension/popup.html').decode()
self.assertIn('Save autofilled login', popup)
self.assertIn('Lock vault', popup)
self.assertIn('Settings', popup)
self.assertNotIn('<iframe', popup)
self.assertNotIn('human-username', popup)
self.assertNotIn('human-password', popup)
self.assertNotIn('juice-panel', popup)
def test_footer_css_and_hero_copy(self):
for name in ('tea/web/🍊/index.html', 'persimmons/web/index.html'):
html = (ROOT / name).read_text()
self.assertIn('🍊 → 💧 → 🤖', html)
self.assertIn('>put plainly</span>', html)
self.assertNotIn('Persimmons are', html)
self.assertNotIn('without paperwork', html)
self.assertNotIn('<div class="footerNote">', html)
hosted = (ROOT / 'persimmons/web/index.html').read_text()
self.assertIn('Master vault', hosted)
self.assertIn('id="namedVaults"', hosted)
self.assertIn('+ New vault', hosted)
self.assertIn('Passwords, PATs &amp; plenty of other useful P’s.', hosted)
self.assertNotIn('My vault', hosted)
self.assertNotIn('id="refreshAll"', hosted)
self.assertIn('id="addCredential"', hosted)
self.assertNotIn('Your Persimmons', hosted)
def test_password_hints_preserve_masking_and_validation(self):
from html.parser import HTMLParser
class Parser(HTMLParser):
def __init__(self):
super().__init__()
self.nodes = {}
def handle_starttag(self, tag, attrs):
attrs = dict(attrs)
if 'id' in attrs:
self.nodes[attrs['id']] = attrs
page = Parser()
page.feed((ROOT / 'persimmons/web/signin.html').read_text())
for name, value in [('signin', 'on'), ('name', 'username'), ('password', 'current-password')]:
self.assertEqual(page.nodes[name]['autocomplete'], value)
self.assertEqual(page.nodes['password']['type'], 'password')
self.assertEqual(page.nodes['password']['minlength'], '12')
self.assertIn('required', page.nodes['password'])