14
14
import asyncio
15
15
import os
16
16
from asyncio .futures import Future
17
+ from pathlib import Path
17
18
from typing import Optional
18
19
19
20
import pytest
20
21
21
- from playwright import Error as PlaywrightError
22
+ from playwright import Error
22
23
from playwright .async_api import Browser , Page
23
24
24
25
@@ -53,10 +54,10 @@ async def test_should_report_downloads_with_acceptDownloads_false(page: Page, se
53
54
download = (await asyncio .gather (page .waitForEvent ("download" ), page .click ("a" )))[0 ]
54
55
assert download .url == f"{ server .PREFIX } /downloadWithFilename"
55
56
assert download .suggestedFilename == "file.txt"
56
- error : Optional [PlaywrightError ] = None
57
+ error : Optional [Error ] = None
57
58
try :
58
59
await download .path ()
59
- except PlaywrightError as exc :
60
+ except Error as exc :
60
61
error = exc
61
62
assert "acceptDownloads" in await download .failure ()
62
63
assert error
@@ -73,6 +74,107 @@ async def test_should_report_downloads_with_acceptDownloads_true(browser, server
73
74
await page .close ()
74
75
75
76
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
+
76
178
async def test_should_report_non_navigation_downloads (browser , server ):
77
179
# Mac WebKit embedder does not download in this case, although Safari does.
78
180
def handle_download (request ):
0 commit comments