Download tests/test_position_window.py from VoiceOfML/Search: direct link, hf CLI and curl.
- Browser
- Download file 22 kB
-
https://huggingface.co/spaces/VoiceOfML/Search/resolve/main/tests/test_position_window.py
- Command line
-
hf download hf://spaces/VoiceOfML/Search/tests/test_position_window.py
-
curl -L -o test_position_window.py https://huggingface.co/spaces/VoiceOfML/Search/resolve/main/tests/test_position_window.py
22 kB
| """Direct deep-position recovery and demand-loaded gaps in real Chromium.""" | |
| import unittest | |
| from tests import test_search_positions as positions | |
| class PositionWindowTests(unittest.TestCase): | |
| def setUpClass(cls): | |
| positions.SearchPositionTests.setUpClass() | |
| def tearDownClass(cls): | |
| positions.SearchPositionTests.tearDownClass() | |
| def setUp(self): | |
| self.fixture = positions.SearchPositionTests() | |
| self.fixture.setUp() | |
| self.page = self.fixture.page | |
| self.page.evaluate("STATE.query='paging-other';doSearch()") | |
| self.page.wait_for_function('!STATE.isLoading') | |
| self.page.evaluate('''() => { | |
| searchViewSnapshots.clear(); | |
| window.windowCalls=[];window.windowFailures=new Set();window.windowGeneration='one'; | |
| window.windowAnchor=49850;window.windowTotal=50001;window.windowStall=0; | |
| window.originalWindowKey=[...searchPositions.keys()].find(key=>JSON.parse(key).query==='paging-original'); | |
| const saved=searchPositions.get(originalWindowKey); | |
| Object.assign(saved,{index:49850,loadedPage:500,anchorId:'VoiceOfML/Test\\0paging-49850.txt',offset:11}); | |
| // Isolate recovery/demand requests from the normal next-page prefetch. | |
| prefetchNextPage=()=>{}; | |
| window.realMaybeLoadNextPage=maybeLoadNextPage;maybeLoadNextPage=()=>{}; | |
| fetchPositionPage=async(query,page,signal,anchorId)=>{ | |
| windowCalls.push(page); | |
| if(windowStall===page) await new Promise(resolve=>window.releaseWindow=resolve); | |
| if(windowFailures.has(page)) throw new Error('offline'); | |
| await new Promise(resolve=>setTimeout(resolve,10)); | |
| const total=windowTotal; | |
| return {page,page_size:query.pageSize,total,generation:windowGeneration,anchor_index:windowAnchor, | |
| results:Array.from({length:Math.min(query.pageSize,Math.max(0,total-(page-1)*query.pageSize))},(_,i)=>{ | |
| const index=(page-1)*query.pageSize+i; | |
| const name=index===windowAnchor?'paging-49850':index===49850?'moved-away':'paging-'+index; | |
| return {Repo:'VoiceOfML/Test',File:name,Extension:'txt',Folder:[],Size:1,ID:String(index)}; | |
| })}; | |
| }; | |
| STATE.query='paging-original';doSearch(false,false,true); | |
| }''') | |
| self.wait_anchor(49850) | |
| def tearDown(self): | |
| errors = self.fixture.fixture.errors[:] | |
| self.fixture.tearDown() | |
| self.assertEqual(errors, []) | |
| def wait_anchor(self, index, offset=11): | |
| self.page.wait_for_function('''({index,offset})=>!positionRestore && !!resultWindow && | |
| findVirtualIndex(getResultScrollTop())===index && !!STATE.results[index] && | |
| Math.abs(getResultScrollTop()-getVirtualOffset(index)-offset)<2''', arg={'index':index,'offset':offset}) | |
| def jump(self, index): | |
| self.page.evaluate('index=>{setResultScrollTop(getVirtualOffset(index)+11);renderVisible()}', index) | |
| def test_depth_500_uses_only_anchor_neighborhood_and_real_loaded_count(self): | |
| self.assertEqual(self.page.evaluate('windowCalls.slice(0,4)'), [1,498,499,500]) | |
| self.assertTrue(self.page.evaluate('windowCalls.every(page=>[1,498,499,500,501].includes(page))')) | |
| self.assertTrue(self.page.evaluate('''() => STATE.total === 50001 && | |
| STATE.results.length >= 50000 && STATE.results.length <= 50001 && | |
| resultWindow.count === Object.keys(STATE.results).length''')) | |
| self.assertEqual(self.page.locator('#current-result-position').input_value(), '49851') | |
| def test_jump_back_fills_only_visible_gap_and_keeps_anchor(self): | |
| self.jump(25050) | |
| self.wait_anchor(25050) | |
| self.assertEqual(self.page.evaluate('STATE.results[25050].File'), 'paging-25050') | |
| self.assertTrue(self.page.evaluate('windowCalls.every(page=>[1,498,499,500,501,248,249,250,251,252,253,254,255,256].includes(page))')) | |
| self.assertEqual(self.page.evaluate('getResultStableId(STATE.results[49850])'), 'VoiceOfML/Test\0paging-49850.txt') | |
| def test_gap_loading_invalidates_snapshot_bytes_and_keeps_prior_snapshot_independent(self): | |
| self.page.evaluate('window.beforeGap=saveSearchViewSnapshot()') | |
| self.jump(25050) | |
| self.wait_anchor(25050) | |
| result = self.page.evaluate('''() => { | |
| const after=saveSearchViewSnapshot(); | |
| return {beforeMissing:!beforeGap.results[25050],afterPresent:!!after.results[25050], | |
| exact:getSearchSnapshotResultsBytes(STATE.results,true)===new TextEncoder().encode(JSON.stringify(STATE.results)).byteLength}; | |
| }''') | |
| self.assertEqual(result, dict(beforeMissing=True, afterPresent=True, exact=True)) | |
| def test_failed_gap_keeps_saved_position_and_can_retry(self): | |
| self.page.set_viewport_size({'width':390,'height':844}) | |
| self.page.evaluate('windowFailures.add(251);saveSearchPosition()') | |
| self.jump(25050) | |
| self.page.locator('#search-window-status').get_by_text('重试加载', exact=True).wait_for() | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 3) | |
| self.page.wait_for_timeout(800) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 3) | |
| self.assertEqual(self.page.evaluate('searchPositions.get(originalWindowKey).index'), 49850) | |
| self.page.evaluate('windowFailures.clear()') | |
| self.page.locator('#search-window-status button').click() | |
| self.wait_anchor(25050) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 4) | |
| def test_transient_gap_failure_recovers_without_click_or_scroll(self): | |
| self.page.evaluate('windowFailures.add(251)') | |
| self.jump(25050) | |
| self.page.wait_for_function('windowCalls.includes(251)') | |
| self.assertEqual(self.page.locator('.result-window-placeholder button').count(), 0) | |
| self.page.evaluate('windowFailures.clear();for(let i=0;i<20;i++)renderVisible()') | |
| self.wait_anchor(25050) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 2) | |
| def test_failed_prefetch_is_bounded_and_does_not_poison_demand(self): | |
| self.page.evaluate('windowFailures.add(251);loadResultWindowPage(251,true)') | |
| self.page.wait_for_function('resultWindow.prefetchFailures?.has(251)') | |
| self.page.evaluate('for(let i=0;i<20;i++)loadResultWindowPage(251,true)') | |
| self.assertFalse(self.page.evaluate('resultWindow.failures.has(251)')) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 1) | |
| self.page.evaluate('windowFailures.clear()') | |
| self.jump(25050) | |
| self.wait_anchor(25050) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 2) | |
| def test_demand_joins_failed_inflight_prefetch_and_owns_retries(self): | |
| self.page.evaluate('windowStall=251;windowFailures.add(251);loadResultWindowPage(251,true);void 0') | |
| self.page.wait_for_function('!!window.releaseWindow') | |
| self.jump(25050) | |
| self.page.evaluate('releaseWindow();windowStall=0') | |
| self.page.wait_for_timeout(100) | |
| self.page.evaluate('windowFailures.clear()') | |
| self.wait_anchor(25050) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 2) | |
| def test_query_change_cancels_retry_delay(self): | |
| self.page.evaluate('windowFailures.add(251)') | |
| self.jump(25050) | |
| self.page.wait_for_function('windowCalls.includes(251)') | |
| self.page.evaluate("STATE.query='paging-latest';doSearch()") | |
| self.page.wait_for_timeout(1000) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 1) | |
| self.assertTrue(self.page.evaluate('resultWindow===null')) | |
| def test_online_recovers_exhausted_visible_page_only(self): | |
| self.page.evaluate('windowFailures.add(251)') | |
| self.jump(25050) | |
| self.page.wait_for_function('resultWindow.failures.has(251)') | |
| self.page.evaluate("resultWindow.failures.set(101,new Error('offline'));windowFailures.clear();window.dispatchEvent(new Event('online'))") | |
| self.wait_anchor(25050) | |
| self.assertTrue(self.page.evaluate('resultWindow.failures.has(101)')) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 4) | |
| self.assertFalse(self.page.evaluate('windowCalls.includes(101)')) | |
| def test_hidden_retry_waits_for_return_and_respects_concurrency(self): | |
| self.page.evaluate('windowFailures.add(251)') | |
| self.jump(25050) | |
| self.page.wait_for_function('windowCalls.includes(251)') | |
| self.page.evaluate("Object.defineProperty(document,'hidden',{configurable:true,value:true})") | |
| self.page.wait_for_timeout(900) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 1) | |
| self.assertLessEqual(self.page.evaluate('resultWindow.pending.size'), 3) | |
| self.page.evaluate("windowFailures.clear();Object.defineProperty(document,'hidden',{configurable:true,value:false});document.dispatchEvent(new Event('visibilitychange'))") | |
| self.wait_anchor(25050) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 2) | |
| def test_restore_retries_lookup_and_missing_neighbor_without_repeating_ready_pages(self): | |
| self.page.evaluate("STATE.query='paging-other';doSearch()") | |
| self.page.wait_for_function('!STATE.isLoading') | |
| self.page.evaluate("searchViewSnapshots.clear();windowCalls=[];windowFailures.add(1);STATE.query='paging-original';doSearch(false,false,true)") | |
| self.page.wait_for_function('windowCalls.includes(1)') | |
| self.page.evaluate('windowFailures.delete(1);windowFailures.add(499)') | |
| self.page.wait_for_function('windowCalls.includes(499)') | |
| self.page.evaluate('windowFailures.clear()') | |
| self.wait_anchor(49850) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===1).length'), 2) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===499).length'), 2) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===498).length'), 1) | |
| def test_retry_policy_excludes_cancel_invalid_data_and_permanent_http_errors(self): | |
| self.assertEqual(self.page.evaluate('''() => { | |
| return [408,429,500,502,503,504,400,403,404].map(status=>isRecoverableSearchError({status})) | |
| .concat([new DOMException('Cancelled','AbortError'),new Error('RESTORE_PAGE_CHANGED'), | |
| new Error('INVALID_API_RESPONSE'),new Error('API_TIMEOUT'),new TypeError('Failed to fetch')].map(isRecoverableSearchError)); | |
| }'''), [True]*6 + [False]*6 + [True,True]) | |
| self.assertEqual(self.page.evaluate('''() => [408,429,403].map(status=>{ | |
| resetPagingRecovery();finishPagingAttempt(false,{status});return pagingFailures; | |
| })'''), [1,1,2]) | |
| def test_generation_change_relocates_without_mixing_pages(self): | |
| self.page.evaluate("saveSearchPosition();windowGeneration='two';windowAnchor=35050") | |
| self.jump(25050) | |
| self.page.locator('#search-window-status').get_by_text('重新定位', exact=True).wait_for() | |
| self.assertFalse(self.page.evaluate('!!STATE.results[25050]')) | |
| self.page.locator('#search-window-status button').click() | |
| self.wait_anchor(35050) | |
| self.assertEqual(self.page.evaluate('STATE.results[35050].File'), 'paging-49850') | |
| self.assertEqual(self.page.evaluate('resultWindow.generation'), 'two') | |
| def test_late_gap_response_cannot_replace_a_new_query(self): | |
| self.page.evaluate('windowStall=251') | |
| self.jump(25050) | |
| self.page.wait_for_function('!!window.releaseWindow') | |
| self.page.evaluate("STATE.query='paging-latest';doSearch();releaseWindow()") | |
| self.page.wait_for_function("STATE.query==='paging-latest' && !STATE.isLoading") | |
| self.page.wait_for_timeout(50) | |
| self.assertTrue(self.page.evaluate('resultWindow===null && STATE.results.length<1000')) | |
| def test_sparse_snapshot_and_selection_keep_only_actual_records(self): | |
| self.page.evaluate('DOM.multiSelectToggle.checked=true;updateSelectionUI();DOM.multiSelectAll.click()') | |
| self.assertTrue(self.page.evaluate('''() => Object.keys(selectedIndices).length >= 400 && | |
| Object.keys(selectedIndices).length <= Object.keys(STATE.results).length''')) | |
| self.assertTrue(self.page.evaluate('Object.keys(selectedIndices).every(index=>!!STATE.results[index])')) | |
| self.page.evaluate("STATE.query='paging-other';doSearch()") | |
| self.page.wait_for_function('!STATE.isLoading') | |
| self.page.evaluate("STATE.query='paging-original';doSearch(false,false,true)") | |
| self.wait_anchor(49850) | |
| self.assertEqual(self.page.evaluate('resultWindow.count'), self.page.evaluate('Object.keys(STATE.results).length')) | |
| self.assertFalse(self.page.evaluate('!!STATE.results[25050]')) | |
| def test_forward_append_reaches_exact_end_and_earlier_pages_remain_accessible(self): | |
| self.page.evaluate('realMaybeLoadNextPage(false,true)') | |
| self.page.wait_for_function('STATE.results.length===50001 && !STATE.hasMore') | |
| self.assertEqual(self.page.evaluate('STATE.results[50000].ID'), '50000') | |
| self.jump(150) | |
| self.wait_anchor(150) | |
| self.assertEqual(self.page.evaluate('STATE.results[150].ID'), '150') | |
| self.assertEqual(self.page.evaluate('STATE.total'), 50001) | |
| def test_drag_defers_gap_application_and_reuses_response_after_release(self): | |
| self.page.evaluate('windowStall=251') | |
| self.jump(25050) | |
| self.page.wait_for_function('!!window.releaseWindow') | |
| self.page.evaluate('VSCROLL.isDraggingThumb=true;releaseWindow()') | |
| self.page.wait_for_function('resultWindow.prefetched?.has(251)') | |
| self.assertFalse(self.page.evaluate('!!STATE.results[25050]')) | |
| self.page.evaluate('VSCROLL.isDraggingThumb=false') | |
| self.jump(35050) | |
| self.wait_anchor(35050) | |
| self.jump(25050) | |
| self.wait_anchor(25050) | |
| self.assertEqual(self.page.evaluate('windowCalls.filter(page=>page===251).length'), 1) | |
| def persist_viewport(self): | |
| self.page.evaluate('''async () => { | |
| searchPositions.get(originalWindowKey).savedAt=0;saveSearchPosition(); | |
| await new Promise(resolve=>{const tx=searchPositionDB.transaction(['positions','viewports']);tx.oncomplete=resolve}); | |
| }''') | |
| def assert_cached_viewport(self, offset=11): | |
| self.page.wait_for_function('positionRestore?.preview && !!window.releaseWindow') | |
| self.assertTrue(self.page.evaluate('''offset => { | |
| const box=DOM.resultsContainer.getBoundingClientRect(); | |
| return findVirtualIndex(getResultScrollTop())===49850 && | |
| Math.abs(getResultScrollTop()-getVirtualOffset(49850)-offset)<2 && | |
| getComputedStyle(DOM.resultsContainer).visibility==='visible' && | |
| [...DOM.resultsList.querySelectorAll('.result-window-placeholder')].every(row=>{ | |
| const rect=row.getBoundingClientRect();return rect.bottom<=box.top || rect.top>=box.bottom; | |
| }); | |
| }''', offset)) | |
| self.assertEqual('49851', self.page.locator('#current-result-position').input_value()) | |
| self.assertTrue(self.page.evaluate('Object.keys(VSCROLL.heights).length<300 && Object.keys(VSCROLL.heightTree).length<2000')) | |
| def test_persisted_viewport_shows_before_lookup_and_keeps_nodes_after_validation(self): | |
| self.persist_viewport() | |
| self.page.evaluate("STATE.query='paging-other';doSearch()") | |
| self.page.wait_for_function('!STATE.isLoading') | |
| self.page.evaluate("searchViewSnapshots.clear();searchViewportSnapshots.clear();windowStall=1;STATE.query='paging-original';doSearch(false,false,true)") | |
| self.assert_cached_viewport() | |
| self.page.evaluate("window.cachedRow=DOM.resultsList.querySelector('[data-index=\"49850\"]');releaseWindow()") | |
| self.wait_anchor(49850) | |
| self.assertTrue(self.page.evaluate("cachedRow===DOM.resultsList.querySelector('[data-index=\"49850\"]')")) | |
| def test_reload_displays_saved_content_while_network_is_blocked(self): | |
| self.page.set_viewport_size({'width':390,'height':844}) | |
| self.page.wait_for_timeout(100) | |
| self.persist_viewport() | |
| # Resizing can change fractional row geometry; restore the saved mobile offset. | |
| saved_offset = self.page.evaluate('searchPositions.get(originalWindowKey).offset') | |
| fetcher = self.page.evaluate('fetchPositionPage.toString()') | |
| self.page.add_init_script('''document.addEventListener('DOMContentLoaded',()=>{ | |
| window.windowCalls=[];window.windowFailures=new Set();window.windowGeneration='one'; | |
| window.windowAnchor=49850;window.windowTotal=50001;window.windowStall=1; | |
| prefetchNextPage=()=>{};maybeLoadNextPage=()=>{};fetchPositionPage=(''' + fetcher + '''); | |
| });''') | |
| self.page.reload(wait_until='domcontentloaded') | |
| self.assert_cached_viewport(saved_offset) | |
| self.page.evaluate('releaseWindow()') | |
| self.wait_anchor(49850, saved_offset) | |
| def test_loading_an_adjacent_page_does_not_replace_visible_rows(self): | |
| self.page.evaluate('window.keptRow=DOM.resultsList.querySelector(\'[data-index="49850"]\');loadResultWindowPage(497)') | |
| self.page.wait_for_function('resultWindow.pages.has(497)') | |
| self.assertTrue(self.page.evaluate('keptRow===DOM.resultsList.querySelector(\'[data-index="49850"]\')')) | |
| self.assertTrue(self.page.evaluate('''() => { | |
| const button=keptRow.querySelector('[data-action="read"]'), before=button.dataset.readerUrl; | |
| readerAssets={[getResultStableId(STATE.results[49850])]:{s:2,m:'p',p:'objects/00/'+'0'.repeat(64)+'/linearized.pdf'}}; | |
| refreshResultReaderActions();renderVisible(); | |
| return keptRow===DOM.resultsList.querySelector('[data-index="49850"]') && | |
| button===keptRow.querySelector('[data-action="read"]') && button.dataset.readerUrl!==before; | |
| }''')) | |
| def test_failed_validation_leaves_cached_content_visible_and_cancels_cleanly(self): | |
| self.persist_viewport() | |
| self.page.evaluate("STATE.query='paging-other';doSearch()") | |
| self.page.wait_for_function('!STATE.isLoading') | |
| self.page.evaluate("searchViewSnapshots.clear();windowFailures.add(1);STATE.query='paging-original';doSearch(false,false,true)") | |
| self.page.get_by_text('重试恢复', exact=True).wait_for() | |
| self.assertEqual(self.page.evaluate('findVirtualIndex(getResultScrollTop())'), 49850) | |
| self.assertEqual(self.page.evaluate('getComputedStyle(DOM.resultsContainer).visibility'), 'visible') | |
| for width in [1280, 390, 320]: | |
| self.page.set_viewport_size({'width': width, 'height': 844}) | |
| self.page.evaluate('STATE.isMobile=innerWidth<600;applyMobileMode()') | |
| self.assertTrue(self.page.locator('#load-info #retry-position-btn').is_visible()) | |
| self.assertTrue(self.page.locator('#retry-position-btn').evaluate('''button=>{ | |
| const retry=button.getBoundingClientRect(),top=document.getElementById('restart-position-btn').getBoundingClientRect(); | |
| const count=document.querySelector('.result-position-count').getBoundingClientRect(); | |
| const bar=document.getElementById('load-info').getBoundingClientRect(); | |
| return [retry,top].every(box=>box.left>=bar.left && box.right<=bar.right && | |
| box.top>=bar.top && box.bottom<=bar.bottom && | |
| !(box.left<count.right && box.right>count.left && box.top<count.bottom && box.bottom>count.top)); | |
| }''')) | |
| self.page.locator('#restart-position-btn').click() | |
| self.page.wait_for_function('!positionRestore && !STATE.isLoading && !resultWindow') | |
| def test_saved_viewport_is_bounded_and_not_used_for_another_anchor(self): | |
| self.persist_viewport() | |
| self.assertLessEqual(self.page.evaluate('searchViewportSnapshots.get(originalWindowKey).records.length'), 80) | |
| self.page.evaluate("STATE.query='paging-other';doSearch()") | |
| self.page.wait_for_function('!STATE.isLoading') | |
| self.page.evaluate("searchViewSnapshots.clear();searchPositions.get(originalWindowKey).anchorId='different';windowStall=1;STATE.query='paging-original';doSearch(false,false,true)") | |
| self.page.wait_for_function('!!window.releaseWindow') | |
| self.assertFalse(self.page.evaluate('!!positionRestore.preview')) | |
| self.page.evaluate('releaseWindow()') | |
| self.wait_anchor(49850) | |
| def test_large_api_records_prioritize_visible_content_within_storage_budget(self): | |
| self.page.evaluate('''() => { | |
| STATE.results.forEach(record=>record.Metadata='中'.repeat(900)); | |
| const original=fetchPositionPage; | |
| fetchPositionPage=async (...args)=>{ | |
| const data=await original(...args);data.results.forEach(record=>record.Metadata='中'.repeat(900));return data; | |
| }; | |
| }''') | |
| self.persist_viewport() | |
| self.assertTrue(self.page.evaluate('''() => { | |
| const saved=searchViewportSnapshots.get(originalWindowKey); | |
| return saved.records.length<80 && new TextEncoder().encode(JSON.stringify(saved)).byteLength<=SEARCH_VIEWPORT_BYTES_MAX; | |
| }''')) | |
| self.page.evaluate("STATE.query='paging-other';doSearch()") | |
| self.page.wait_for_function('!STATE.isLoading') | |
| self.page.evaluate("searchViewSnapshots.clear();searchViewportSnapshots.clear();windowStall=1;STATE.query='paging-original';doSearch(false,false,true)") | |
| self.assert_cached_viewport() | |
| self.page.evaluate('releaseWindow()') | |
| self.wait_anchor(49850) | |