/** * SOKUJA Scraper Test Suite * Run with: node test.js */ const SokujaScraper = require('./index'); const scraper = new SokujaScraper(); let passed = 0; let failed = 0; async function test(name, fn) { try { console.log(`\nšŸ“ Testing: ${name}...`); const result = await fn(); console.log(`āœ… PASSED: ${name}`); if (result) console.log(` Result:`, JSON.stringify(result, null, 2).substring(0, 200)); passed++; return result; } catch (error) { console.log(`āŒ FAILED: ${name}`); console.log(` Error: ${error.message}`); failed++; return null; } } async function runTests() { console.log('═══════════════════════════════════════════'); console.log(' SOKUJA SCRAPER TEST SUITE '); console.log('═══════════════════════════════════════════'); // Test 1: Home Page await test('Get Home Data Complete', async () => { const home = await scraper.getHomeComplete(); if (!home) throw new Error('No data returned'); return { heroCount: home.hero?.length }; }); // Test 2: Ongoing await test('Get Ongoing Anime', async () => { const ongoing = await scraper.getOngoing(1); if (!ongoing.anime || ongoing.anime.length === 0) throw new Error('No ongoing anime found'); return { count: ongoing.anime.length, first: ongoing.anime[0]?.title }; }); // Test 3: Completed await test('Get Completed Anime', async () => { const completed = await scraper.getCompleted(1); return { count: completed.anime?.length }; }); // Test 4: Anime Detail const sampleSlug = 'the-beginning-after-the-end-season-2-subtitle-indonesia'; await test('Get Anime Detail', async () => { const detail = await scraper.getAnimeDetail(sampleSlug); if (!detail.title) throw new Error('No title found'); if (!detail.episodes || detail.episodes.length === 0) throw new Error('No episodes found'); return { title: detail.title, episodes: detail.episodes.length, genres: detail.genres?.length }; }); // Test 5: Episode Detail await test('Get Episode Detail', async () => { const ep = await scraper.getEpisodeDetail(sampleSlug, 1); if (!ep.title) throw new Error('No episode title'); return { episode: ep.episode, title: ep.title, downloads: ep.downloads?.video?.length }; }); // Test 6: Schedule await test('Get Schedule', async () => { const schedule = await scraper.getSchedule(); if (!schedule.senin || !schedule.rabu) throw new Error('Days missing'); return { senin: schedule.senin.length, rabu: schedule.rabu.length, sabtu: schedule.sabtu.length }; }); // Test 7: Genres await test('Get Genres', async () => { const genres = await scraper.getGenres(); if (!genres || genres.length === 0) throw new Error('No genres found'); return { count: genres.length, first: genres[0]?.name }; }); // Test 8: Search await test('Search Anime', async () => { const search = await scraper.searchAnime('piece'); return { results: search.results.length, query: search.query }; }); // Test 9: Movies await test('Get Movies', async () => { const movies = await scraper.getMovies(1); return { count: movies.anime?.length }; }); // Test 10: Genre Anime await test('Get Anime by Genre', async () => { const genreAnime = await scraper.getByGenre('fantasy', 1); return { count: genreAnime.anime?.length }; }); // Summary console.log('\n═══════════════════════════════════════════'); console.log(` Tests Complete: ${passed} passed, ${failed} failed`); console.log('═══════════════════════════════════════════'); if (failed > 0) { process.exit(1); } } // Handle errors process.on('unhandledRejection', (err) => { console.error('Unhandled rejection:', err); process.exit(1); }); runTests().catch(err => { console.error('Test suite error:', err); process.exit(1); });