# retoor 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()