Files

157 lines
4.7 KiB
Python
Raw Permalink Normal View History

# retoor <retoor@molodetz.nl>
import pytest
from stealthii import Stealthii, StealthRequestError
@pytest.fixture
async def stealth():
s = Stealthii()
yield s
await s.shutdown()
@pytest.mark.online
@pytest.mark.asyncio
async def test_get_json(stealth):
resp = await stealth.get('https://httpbin.org/get', params={'a': '1'})
assert resp.status == 200
assert (await resp.json())['args'] == {'a': '1'}
@pytest.mark.online
@pytest.mark.asyncio
async def test_post_json_body(stealth):
resp = await stealth.post('https://httpbin.org/post', json={'hello': 'world'})
assert resp.status == 200
assert (await resp.json())['json'] == {'hello': 'world'}
@pytest.mark.online
@pytest.mark.asyncio
async def test_post_form_data(stealth):
resp = await stealth.post('https://httpbin.org/post', data={'x': '1', 'y': '2'})
assert resp.status == 200
assert (await resp.json())['form'] == {'x': '1', 'y': '2'}
@pytest.mark.online
@pytest.mark.asyncio
async def test_put(stealth):
resp = await stealth.put('https://httpbin.org/put', json={'k': 'v'})
assert resp.status == 200
assert (await resp.json())['json'] == {'k': 'v'}
@pytest.mark.online
@pytest.mark.asyncio
async def test_patch(stealth):
resp = await stealth.patch('https://httpbin.org/patch', json={'k': 'v'})
assert resp.status == 200
@pytest.mark.online
@pytest.mark.asyncio
async def test_delete(stealth):
resp = await stealth.delete('https://httpbin.org/delete')
assert resp.status == 200
@pytest.mark.online
@pytest.mark.asyncio
async def test_head(stealth):
resp = await stealth.head('https://httpbin.org/get')
assert resp.status == 200
@pytest.mark.online
@pytest.mark.asyncio
async def test_per_call_cookies_layer_on_context_jar(stealth):
resp = await stealth.get('https://httpbin.org/cookies', cookies={'flavor': 'choc'})
assert (await resp.json())['cookies'] == {'flavor': 'choc'}
@pytest.mark.online
@pytest.mark.asyncio
async def test_basic_auth(stealth):
ok = await stealth.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))
assert ok.status == 200
bad = await stealth.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'wrong'))
assert bad.status == 401
@pytest.mark.online
@pytest.mark.asyncio
async def test_download_binary(stealth):
data = await stealth.download('https://httpbin.org/image/png')
assert data[:8] == b'\x89PNG\r\n\x1a\n'
@pytest.mark.online
@pytest.mark.asyncio
async def test_multipart_file_upload(stealth):
resp = await stealth.post(
'https://httpbin.org/post',
data={'field': 'value'},
files={'upload': ('name.txt', b'file-content')},
)
body = await resp.json()
assert body['form'] == {'field': 'value'}
assert body['files']['upload'] == 'file-content'
@pytest.mark.online
@pytest.mark.asyncio
async def test_render_returns_text_and_links(stealth):
out = await stealth.render('https://example.com', collect_links=True)
assert out['status'] == 200
assert 'Example Domain' in out['text']
assert isinstance(out['links'], list)
@pytest.mark.online
@pytest.mark.asyncio
async def test_screenshot_base64_and_path(stealth, tmp_path):
b64 = await stealth.screenshot('https://example.com')
assert len(b64) > 1000
out_path = str(tmp_path / 'shot.png')
result_path = await stealth.screenshot('https://example.com', path=out_path)
assert result_path == out_path
with open(out_path, 'rb') as f:
assert f.read(8) == b'\x89PNG\r\n\x1a\n'
@pytest.mark.online
@pytest.mark.asyncio
async def test_named_session_persists_cookies_across_calls(stealth):
await stealth.get('https://httpbin.org/cookies/set/persisted/yes', session='warm')
resp = await stealth.get('https://httpbin.org/cookies', session='warm')
assert (await resp.json())['cookies'] == {'persisted': 'yes'}
@pytest.mark.online
@pytest.mark.asyncio
async def test_anonymous_calls_do_not_share_named_session_cookies(stealth):
await stealth.get('https://httpbin.org/cookies/set/persisted/yes', session='isolated')
resp = await stealth.get('https://httpbin.org/cookies')
assert (await resp.json())['cookies'] == {}
@pytest.mark.online
@pytest.mark.asyncio
async def test_request_raises_stealth_request_error_on_unreachable_host(stealth):
with pytest.raises(StealthRequestError):
await stealth.get('https://this-host-does-not-exist.invalid/', timeout=3)
@pytest.mark.online
@pytest.mark.asyncio
async def test_page_and_context_close_even_when_caller_raises(stealth):
pages = []
with pytest.raises(ValueError):
async with stealth.page() as pg:
pages.append(pg)
raise ValueError('boom')
assert pages[0].is_closed()