1414import asyncio
1515import os
1616from asyncio .futures import Future
17+ from pathlib import Path
1718from typing import Optional
1819
1920import pytest
2021
21- from playwright import Error as PlaywrightError
22+ from playwright import Error
2223from playwright .async_api import Browser , Page
2324
2425
@@ -53,10 +54,10 @@ async def test_should_report_downloads_with_acceptDownloads_false(page: Page, se
5354 download = (await asyncio .gather (page .waitForEvent ("download" ), page .click ("a" )))[0 ]
5455 assert download .url == f"{ server .PREFIX } /downloadWithFilename"
5556 assert download .suggestedFilename == "file.txt"
56- error : Optional [PlaywrightError ] = None
57+ error : Optional [Error ] = None
5758 try :
5859 await download .path ()
59- except PlaywrightError as exc :
60+ except Error as exc :
6061 error = exc
6162 assert "acceptDownloads" in await download .failure ()
6263 assert error
@@ -73,6 +74,107 @@ async def test_should_report_downloads_with_acceptDownloads_true(browser, server
7374 await page .close ()
7475
7576
77+ async def test_should_save_to_user_specified_path (tmpdir : Path , browser , server ):
78+ page = await browser .newPage (acceptDownloads = True )
79+ await page .setContent (f'<a href="{ server .PREFIX } /download">download</a>' )
80+ [download , _ ] = await asyncio .gather (page .waitForEvent ("download" ), page .click ("a" ))
81+ user_path = tmpdir / "download.txt"
82+ await download .saveAs (user_path )
83+ assert user_path .exists ()
84+ assert user_path .read_text ("utf-8" ) == "Hello world"
85+ await page .close ()
86+
87+
88+ async def test_should_save_to_user_specified_path_without_updating_original_path (
89+ tmpdir , browser , server
90+ ):
91+ page = await browser .newPage (acceptDownloads = True )
92+ await page .setContent (f'<a href="{ server .PREFIX } /download">download</a>' )
93+ [download , _ ] = await asyncio .gather (page .waitForEvent ("download" ), page .click ("a" ))
94+ user_path = tmpdir / "download.txt"
95+ await download .saveAs (user_path )
96+ assert user_path .exists ()
97+ assert user_path .read_text ("utf-8" ) == "Hello world"
98+
99+ originalPath = Path (await download .path ())
100+ assert originalPath .exists ()
101+ assert originalPath .read_text ("utf-8" ) == "Hello world"
102+ await page .close ()
103+
104+
105+ async def test_should_save_to_two_different_paths_with_multiple_saveAs_calls (
106+ tmpdir , browser , server
107+ ):
108+ page = await browser .newPage (acceptDownloads = True )
109+ await page .setContent (f'<a href="{ server .PREFIX } /download">download</a>' )
110+ [download , _ ] = await asyncio .gather (page .waitForEvent ("download" ), page .click ("a" ))
111+ user_path = tmpdir / "download.txt"
112+ await download .saveAs (user_path )
113+ assert user_path .exists ()
114+ assert user_path .read_text ("utf-8" ) == "Hello world"
115+
116+ anotheruser_path = tmpdir / "download (2).txt"
117+ await download .saveAs (anotheruser_path )
118+ assert anotheruser_path .exists ()
119+ assert anotheruser_path .read_text ("utf-8" ) == "Hello world"
120+ await page .close ()
121+
122+
123+ async def test_should_save_to_overwritten_filepath (tmpdir : Path , browser , server ):
124+ page = await browser .newPage (acceptDownloads = True )
125+ await page .setContent (f'<a href="{ server .PREFIX } /download">download</a>' )
126+ [download , _ ] = await asyncio .gather (page .waitForEvent ("download" ), page .click ("a" ))
127+ user_path = tmpdir / "download.txt"
128+ await download .saveAs (user_path )
129+ assert len (list (Path (tmpdir ).glob ("*.*" ))) == 1
130+ await download .saveAs (user_path )
131+ assert len (list (Path (tmpdir ).glob ("*.*" ))) == 1
132+ assert user_path .exists ()
133+ assert user_path .read_text ("utf-8" ) == "Hello world"
134+ await page .close ()
135+
136+
137+ async def test_should_create_subdirectories_when_saving_to_non_existent_user_specified_path (
138+ tmpdir , browser , server
139+ ):
140+ page = await browser .newPage (acceptDownloads = True )
141+ await page .setContent (f'<a href="{ server .PREFIX } /download">download</a>' )
142+ [download , _ ] = await asyncio .gather (page .waitForEvent ("download" ), page .click ("a" ))
143+ nested_path = tmpdir / "these" / "are" / "directories" / "download.txt"
144+ await download .saveAs (nested_path )
145+ assert nested_path .exists ()
146+ assert nested_path .read_text ("utf-8" ) == "Hello world"
147+ await page .close ()
148+
149+
150+ async def test_should_error_when_saving_with_downloads_disabled (
151+ tmpdir , browser , server
152+ ):
153+ page = await browser .newPage (acceptDownloads = False )
154+ await page .setContent (f'<a href="{ server .PREFIX } /download">download</a>' )
155+ [download , _ ] = await asyncio .gather (page .waitForEvent ("download" ), page .click ("a" ))
156+ user_path = tmpdir / "download.txt"
157+ with pytest .raises (Error ) as exc :
158+ await download .saveAs (user_path )
159+ assert (
160+ "Pass { acceptDownloads: true } when you are creating your browser context"
161+ in exc .value .message
162+ )
163+ await page .close ()
164+
165+
166+ async def test_should_error_when_saving_after_deletion (tmpdir , browser , server ):
167+ page = await browser .newPage (acceptDownloads = True )
168+ await page .setContent (f'<a href="{ server .PREFIX } /download">download</a>' )
169+ [download , _ ] = await asyncio .gather (page .waitForEvent ("download" ), page .click ("a" ))
170+ user_path = tmpdir / "download.txt"
171+ await download .delete ()
172+ with pytest .raises (Error ) as exc :
173+ await download .saveAs (user_path )
174+ assert "Download already deleted. Save before deleting." in exc .value .message
175+ await page .close ()
176+
177+
76178async def test_should_report_non_navigation_downloads (browser , server ):
77179 # Mac WebKit embedder does not download in this case, although Safari does.
78180 def handle_download (request ):
0 commit comments