puppeteer-autoscroll-down
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -5,2 +5,6 @@ # Change Log | ||
## 1.1.0 | ||
- Added `scrollPageToTop`. | ||
## 1.0.0 | ||
@@ -7,0 +11,0 @@ |
@@ -24,3 +24,3 @@ import { Page } from 'puppeteer-core' | ||
/** | ||
* Scrolling page to bottom | ||
* Scrolling page to the bottom | ||
* | ||
@@ -40,1 +40,18 @@ * @example | ||
export declare function scrollPageToBottom(page: Page, options: Options): Promise<number> | ||
/** | ||
* Scrolling page to the top | ||
* | ||
* @example | ||
* ```js | ||
* const browser = await puppeteer.launch() | ||
* const page = await browser.newPage() | ||
* await page.goto("https://en.wikipedia.org/wiki/Main_Page") | ||
* const lastPosition = await scrollPageToTop(page) | ||
* await browser.close() | ||
* ``` | ||
* @param {Page} page | ||
* @param {Options} options | ||
* @returns {Promise<number>} | ||
*/ | ||
export declare function scrollPageToTop(page: Page, options: Options): Promise<number> |
74
index.js
@@ -1,40 +0,48 @@ | ||
async function scrollPageToBottom(page, { size = 250, delay = 100, stepsLimit = null } = {}) { | ||
let lastScrollPosition = await page.evaluate( | ||
async (pixelsToScroll, delayAfterStep, limit) => { | ||
let getElementScrollHeight = element => { | ||
if (!element) return 0 | ||
let { scrollHeight, offsetHeight, clientHeight } = element | ||
return Math.max(scrollHeight, offsetHeight, clientHeight) | ||
} | ||
function scrollPage(scrollDirection) { | ||
return async (page, { size = 250, delay = 100, stepsLimit = null } = {}) => { | ||
let lastScrollPosition = await page.evaluate( | ||
async (pixelsToScroll, delayAfterStep, limit, direction) => { | ||
let getElementScrollHeight = element => { | ||
if (!element) return 0 | ||
let { scrollHeight, offsetHeight, clientHeight } = element | ||
return Math.max(scrollHeight, offsetHeight, clientHeight) | ||
} | ||
let scrollToBottom = resolve => { | ||
let lastPosition = 0 | ||
let initialScrollPosition = window.pageYOffset | ||
let availableScrollHeight = getElementScrollHeight(document.body) | ||
let lastPosition = direction === 'bottom' ? 0 : initialScrollPosition | ||
let intervalId = setInterval(() => { | ||
let { body } = document | ||
let availableScrollHeight = getElementScrollHeight(body) | ||
let scrollFn = resolve => { | ||
let intervalId = setInterval(() => { | ||
window.scrollBy(0, direction === 'bottom' ? pixelsToScroll : -pixelsToScroll) | ||
lastPosition += direction === 'bottom' ? pixelsToScroll : -pixelsToScroll | ||
window.scrollBy(0, pixelsToScroll) | ||
lastPosition += pixelsToScroll | ||
if ( | ||
(direction === 'bottom' && lastPosition >= availableScrollHeight) || | ||
(direction === 'bottom' && | ||
limit !== null && | ||
lastPosition >= pixelsToScroll * limit) || | ||
(direction === 'top' && lastPosition <= 0) || | ||
(direction === 'top' && | ||
limit !== null && | ||
lastPosition <= initialScrollPosition - pixelsToScroll * limit) | ||
) { | ||
clearInterval(intervalId) | ||
resolve(lastPosition) | ||
} | ||
}, delayAfterStep) | ||
} | ||
if ( | ||
lastPosition >= availableScrollHeight || | ||
(limit !== null && lastPosition >= pixelsToScroll * limit) | ||
) { | ||
clearInterval(intervalId) | ||
resolve(lastPosition) | ||
} | ||
}, delayAfterStep) | ||
} | ||
return new Promise(scrollFn) | ||
}, | ||
size, | ||
delay, | ||
stepsLimit, | ||
scrollDirection | ||
) | ||
return new Promise(scrollToBottom) | ||
}, | ||
size, | ||
delay, | ||
stepsLimit | ||
) | ||
return lastScrollPosition | ||
return lastScrollPosition | ||
} | ||
} | ||
module.exports = { scrollPageToBottom } | ||
module.exports = { scrollPageToBottom: scrollPage('bottom'), scrollPageToTop: scrollPage('top') } |
{ | ||
"name": "puppeteer-autoscroll-down", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Handle infinite scroll on websites with puppeteer", | ||
@@ -31,16 +31,16 @@ "main": "index.js", | ||
"devDependencies": { | ||
"@logux/eslint-config": "^46.1.0", | ||
"@types/puppeteer": "^5.4.4", | ||
"check-dts": "^0.6.5", | ||
"eslint": "^8.4.1", | ||
"@logux/eslint-config": "^46.1.1", | ||
"@types/puppeteer": "^5.4.5", | ||
"check-dts": "^0.6.6", | ||
"eslint": "^8.10.0", | ||
"eslint-config-standard": "^16.0.3", | ||
"eslint-plugin-import": "^2.25.3", | ||
"eslint-plugin-import": "^2.25.4", | ||
"eslint-plugin-node": "^11.1.0", | ||
"eslint-plugin-prefer-let": "^3.0.1", | ||
"eslint-plugin-promise": "^5.2.0", | ||
"eslint-plugin-promise": "^6.0.0", | ||
"find-chrome-bin": "^0.1.0", | ||
"puppeteer-core": "^13.0.0", | ||
"puppeteer-core": "^13.4.0", | ||
"tsm": "^2.2.1", | ||
"typescript": "^4.5.3", | ||
"uvu": "^0.5.2" | ||
"typescript": "^4.5.5", | ||
"uvu": "^0.5.3" | ||
}, | ||
@@ -47,0 +47,0 @@ "keywords": [ |
@@ -7,7 +7,7 @@ # Handle infinite scroll on websites with puppeteer | ||
**`size` - Number of pixels to scroll on each step** `[default: 250]`. | ||
**`size` - Number of pixels to scroll on each step** `[default: 250]` | ||
**`delay` - Delay in ms after each completed scroll step** `[default: 100]`. | ||
**`delay` - Delay in ms after each completed scroll step** `[default: 100]` | ||
**`stepsLimit` - Max number of steps to scroll** `[default: null]`. | ||
**`stepsLimit` - Max number of steps to scroll** `[default: null]` | ||
@@ -32,3 +32,3 @@ ```js | ||
**You can use returned value with request/response hooks to handle async content loading.** | ||
**You can use returned value with request/response hooks to handle async content loading** | ||
@@ -56,5 +56,25 @@ ```js | ||
### Not only scroll to the bottom, but there is also function for scroll to the top | ||
**`scrollPageToTop` supports same API as `scrollPageToBottom`** | ||
```js | ||
const puppeteer = require('puppeteer') | ||
const { scrollPageToTop } = require('puppeteer-autoscroll-down') | ||
const browser = await puppeteer.launch() | ||
const page = await browser.newPage() | ||
await page.goto('http://example.com') | ||
const lastPosition = await scrollPageToTop(page, { | ||
size: 500, | ||
delay: 250 | ||
}) | ||
await browser.close() | ||
``` | ||
## Install | ||
```js | ||
```sh | ||
npm i puppeteer-autoscroll-down | ||
@@ -65,3 +85,3 @@ ``` | ||
```js | ||
```sh | ||
yarn add puppeteer-autoscroll-down | ||
@@ -68,0 +88,0 @@ ``` |
@@ -8,3 +8,3 @@ const { test } = require('uvu') | ||
const { scrollPageToBottom } = require('../index') | ||
const { scrollPageToBottom, scrollPageToTop } = require('../index') | ||
@@ -20,2 +20,3 @@ test('should scroll `regular` page to bottom', async () => { | ||
let isScrolledToBottom = false | ||
let lastPosition = 0 | ||
@@ -25,4 +26,7 @@ try { | ||
await page.goto(`file://${join(__dirname, 'stub', 'regular-page.html')}`) | ||
await scrollPageToBottom(page) | ||
lastPosition = await scrollPageToBottom(page) | ||
isScrolledToBottom = await page.evaluate(() => isInViewport(document.querySelector('#test'))) // eslint-disable-line no-undef | ||
assert.is(isScrolledToBottom, true) | ||
assert.is(lastPosition > 0, true) | ||
} catch (error) { | ||
@@ -35,4 +39,2 @@ console.error(error) // eslint-disable-line no-console | ||
} | ||
assert.equal(isScrolledToBottom, true) | ||
}) | ||
@@ -49,2 +51,3 @@ | ||
let isScrolledToBottom = false | ||
let lastPosition = 0 | ||
@@ -54,5 +57,6 @@ try { | ||
await page.goto(`file://${join(__dirname, 'stub', 'async-content-page.html')}`) | ||
let isLoadingAvailable = !(await page.evaluate(() => | ||
document.querySelector('#loader').classList.contains('hide') | ||
)) | ||
let isLoadingAvailable | ||
while (isLoadingAvailable) { | ||
@@ -62,3 +66,3 @@ isLoadingAvailable = !(await page.evaluate(() => | ||
)) | ||
await scrollPageToBottom(page, { size: 500 }) | ||
lastPosition = await scrollPageToBottom(page, { size: 100 }) | ||
await page.waitForTimeout(1500) | ||
@@ -68,2 +72,5 @@ } | ||
isScrolledToBottom = await page.evaluate(() => isInViewport(document.querySelector('#test'))) // eslint-disable-line no-undef | ||
assert.is(isScrolledToBottom, true) | ||
assert.is(lastPosition > 0, true) | ||
} catch (error) { | ||
@@ -76,6 +83,36 @@ console.error(error) // eslint-disable-line no-console | ||
} | ||
}) | ||
assert.equal(isScrolledToBottom, true) | ||
test('should scroll page to top', async () => { | ||
let chromeInfo = await findChrome({ | ||
download: { puppeteer, revision: PUPPETEER_REVISIONS.chromium, path: join(__dirname, 'chrome') } | ||
}) | ||
let browser = await puppeteer.launch({ | ||
headless: true, | ||
executablePath: chromeInfo.executablePath | ||
}) | ||
let lastPosition = 0 | ||
try { | ||
let page = await browser.newPage() | ||
await page.goto(`file://${join(__dirname, 'stub', 'regular-page.html')}`) | ||
lastPosition = await scrollPageToBottom(page) | ||
let isScrolledToBottom = await page.evaluate( | ||
() => isInViewport(document.querySelector('#test')) // eslint-disable-line no-undef | ||
) | ||
assert.is(isScrolledToBottom, true) | ||
assert.is(lastPosition > 0, true) | ||
lastPosition = await scrollPageToTop(page) | ||
assert.is(lastPosition === 0, true) | ||
} catch (error) { | ||
console.error(error) // eslint-disable-line no-console | ||
} finally { | ||
let pages = await browser.pages() | ||
await Promise.all(pages.map(item => item.close())) | ||
await browser.close() | ||
} | ||
}) | ||
test.run() |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
61775
187
89
0
11