28
28
* node verify_download.js
29
29
*/
30
30
31
- const puppeteer = require ( 'puppeteer' ) ;
32
31
const fs = require ( 'fs' ) ;
33
- const path = require ( 'path' ) ;
34
32
const os = require ( 'os' ) ;
33
+ const path = require ( 'path' ) ;
34
+ const puppeteer = require ( 'puppeteer' ) ;
35
35
36
- const DOWNLOADS_FOLDER = ` ${ os . homedir ( ) } /Downloads` ;
36
+ const DOWNLOAD_PATH = path . resolve ( __dirname , 'downloads' ) ;
37
37
38
38
/**
39
39
* From @xprudhomme.
@@ -43,9 +43,9 @@ const DOWNLOADS_FOLDER = `${os.homedir()}/Downloads`;
43
43
* @param {string } filePath
44
44
* @param {integer } timeout
45
45
* @returns {!Promise<undefined> } Resolves when file has been created. Rejects
46
- * if timout is reached.
46
+ * if timeout is reached.
47
47
*/
48
- function checkFileExists ( filePath , timeout = 15000 ) {
48
+ function waitForFileExists ( filePath , timeout = 15000 ) {
49
49
return new Promise ( ( resolve , reject ) => {
50
50
const dir = path . dirname ( filePath ) ;
51
51
const basename = path . basename ( filePath ) ;
@@ -73,96 +73,59 @@ function checkFileExists(filePath, timeout=15000) {
73
73
} ) ;
74
74
}
75
75
76
- /**
77
- * @param {!Browser } browser
78
- * @param {string } url The URL of the download file to wait for.
79
- * @returns {!Promise<!Object> } Metadata about the latest file in Download Manager.
80
- */
81
- async function waitForFileToDownload ( browser , url ) {
82
- const downloadPage = await browser . newPage ( ) ;
83
- // Note: navigating to this page only works in headful chrome.
84
- await downloadPage . goto ( 'chrome://downloads/' ) ;
85
-
86
- // Wait for our download to show up in the list by matching on its url.
87
- const jsHandle = await downloadPage . waitForFunction ( downloadUrl => {
88
- const manager = document . querySelector ( 'downloads-manager' ) ;
89
- const downloads = manager . items_ . length ;
90
- const lastDownload = manager . items_ [ 0 ] ;
91
- if ( downloads && lastDownload . url === downloadUrl &&
92
- lastDownload . state === 'COMPLETE' ) {
93
- return manager . items_ [ 0 ] ;
94
- }
95
- } , { polling : 100 } , url ) ;
96
-
97
- const fileMeta = await jsHandle . jsonValue ( ) ;
98
-
99
- await downloadPage . close ( ) ;
100
-
101
- return fileMeta ;
102
- }
103
-
104
- /**
105
- * @param {!Browser } browser
106
- * @param {string } url The url of the page to navigate to.
107
- * @param {string } text The link with this text to find and click on the page.
108
- * @returns {!Promise<?string> } The download resource's url.
109
- */
110
- async function clickDownloadLink ( browser , url , text ) {
111
- const page = await browser . newPage ( ) ;
112
- await page . goto ( url , { waitUntil : 'networkidle2' } ) ;
113
-
114
- const downloadUrl = await page . evaluate ( ( text ) => {
115
- const link = document . evaluate ( `//a[text()="${ text } "]` , document ,
116
- null , XPathResult . FIRST_ORDERED_NODE_TYPE , null ) . singleNodeValue ;
117
- if ( link ) {
118
- link . click ( ) ;
119
- return link . href ;
120
- }
121
- return null ;
122
- } , text ) ;
123
-
124
- await page . close ( ) ;
125
-
126
- return downloadUrl ;
127
- }
128
-
129
76
( async ( ) => {
130
77
131
- const browser = await puppeteer . launch ( {
132
- headless : false ,
133
- // dumpio: true,
134
- } ) ;
78
+ const browser = await puppeteer . launch ( ) ;
135
79
136
- // TODO: setDownloadBehavior would be a good approach, as we could check
137
- // that the file shows up in the location specified by downloadPath. Howeverm
138
- // that arg doesn't currently work.
139
- // const client = await page.target().createCDPSession();
140
- // await client.send('Page.setDownloadBehavior', {
141
- // behavior: 'allow',
142
- // downloadPath: path.resolve(__dirname, 'downloads'),
143
- // });
80
+ const page = await browser . newPage ( ) ;
144
81
145
- // await client.detach();
82
+ // Change from the default ~/Downloads folder to our own.
83
+ const client = await page . target ( ) . createCDPSession ( ) ;
84
+ await client . send ( 'Page.setDownloadBehavior' , {
85
+ behavior : 'allow' ,
86
+ downloadPath : DOWNLOAD_PATH ,
87
+ } ) ;
146
88
147
- // 1. navigate to a page with a bunch links to download.
148
- // 2. click the "Short Selling (csv)" link on the page. The browser force downloads the file.
149
89
const url = 'https://www.nseindia.com/products/content/equities/equities/homepage_eq.htm' ;
150
- const downloadUrl = await clickDownloadLink ( browser , url , 'Short Selling (csv)' ) ;
90
+ await page . goto ( url ) ;
91
+ // Wait for main content area to have list of links.
92
+ await page . waitForSelector ( '.main_content' , { visible : true , timeout : 5000 } ) ;
93
+
94
+ const downloadUrl = await page . evaluate ( ( ) => {
95
+ const link = document . evaluate ( `//a[text()="Short Selling (csv)"]` , document ,
96
+ null , XPathResult . FIRST_ORDERED_NODE_TYPE , null ) . singleNodeValue ;
97
+ if ( link ) {
98
+ // Prevent link from opening up in a new tab. Puppeteer won't respect
99
+ // the Page.setDownloadBehavior on the new tab and the file ends up in the
100
+ // default download folder.
101
+ link . target = '' ;
102
+ link . click ( ) ;
103
+ return link . href ;
104
+ }
105
+ return null ;
106
+ } ) ;
151
107
152
108
if ( ! downloadUrl ) {
153
- console . error ( 'Did not find download link!' ) ;
109
+ console . warn ( 'Did not find link to download!' ) ;
110
+ await browser . close ( ) ;
154
111
return ;
155
112
}
156
113
157
- // 3. Open chrome:downloads and wait for the file to be downloaded.
158
- const fileMeta = await waitForFileToDownload ( browser , downloadUrl ) ;
159
- console . log ( `"${ fileMeta . file_name } " was downloaded` ) ;
114
+ // Wait for file response to complete.
115
+ await new Promise ( resolve => {
116
+ page . on ( 'response' , async resp => {
117
+ if ( resp . url ( ) === downloadUrl ) {
118
+ resolve ( ) ;
119
+ }
120
+ } ) ;
121
+ } ) ;
122
+
123
+ console . log ( 'Downloaded.' ) ;
160
124
161
- // 4. Optionally check that the file really ends up in the expected location
162
- // on the filesystem.
163
- const exists = await checkFileExists ( `${ DOWNLOADS_FOLDER } /${ fileMeta . file_name } ` ) ;
164
- console . assert ( exists , `${ fileMeta . file_name } was not downloaded to correct location.` ) ;
125
+ // Verify it's on the file system.
126
+ await waitForFileExists ( `${ DOWNLOAD_PATH } /ShortSelling.csv` ) ;
127
+ console . log ( 'Exists!' ) ;
165
128
166
129
await browser . close ( ) ;
167
130
168
- } ) ( ) ;
131
+ } ) ( ) ;
0 commit comments