Best Playwright-dotnet code snippet using Microsoft.Playwright.Core.Stream.Close
BrowserTypeConnectTests.cs
Source:BrowserTypeConnectTests.cs
...46 }47 [TearDown]48 public void TearDownRemoteServer()49 {50 _remoteServer.Close();51 }52 [PlaywrightTest("browsertype-connect.spec.ts", "should be able to reconnect to a browser")]53 public async Task ShouldBeAbleToReconnectToABrowser()54 {55 {56 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);57 var browserContext = await browser.NewContextAsync();58 Assert.AreEqual(browserContext.Pages.Count, 0);59 var page = await browserContext.NewPageAsync();60 Assert.AreEqual(await page.EvaluateAsync<int>("11 * 11"), 121);61 await page.GotoAsync(Server.EmptyPage);62 await browser.CloseAsync();63 }64 {65 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);66 var browserContext = await browser.NewContextAsync();67 var page = await browserContext.NewPageAsync();68 await page.GotoAsync(Server.EmptyPage);69 await browser.CloseAsync();70 }71 }72 [PlaywrightTest("browsertype-connect.spec.ts", "should send default User-Agent and X-Playwright-Browser headers with connect request")]73 public async Task ShouldSendDefaultUserAgentAndPlaywrightBrowserHeadersWithConnectRequest()74 {75 var connectionRequest = Server.WaitForWebSocketConnectionRequest();76 BrowserType.ConnectAsync($"ws://localhost:{Server.Port}/ws", new()77 {78 Headers = new Dictionary<string, string>()79 {80 ["hello-foo"] = "i-am-bar",81 }82 }).IgnoreException();83 var request = await connectionRequest;84 StringAssert.Contains("Playwright", request.Headers["User-Agent"]);85 Assert.AreEqual(request.Headers["hello-foo"], "i-am-bar");86 Assert.AreEqual(request.Headers["x-playwright-browser"], BrowserType.Name);87 }88 [PlaywrightTest("browsertype-connect.spec.ts", "should be able to connect two browsers at the same time")]89 public async Task ShouldBeAbleToConnectTwoBrowsersAtTheSameTime()90 {91 var browser1 = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);92 Assert.AreEqual(browser1.Contexts.Count, 0);93 await browser1.NewContextAsync();94 Assert.AreEqual(browser1.Contexts.Count, 1);95 var browser2 = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);96 Assert.AreEqual(browser2.Contexts.Count, 0);97 await browser2.NewContextAsync();98 Assert.AreEqual(browser2.Contexts.Count, 1);99 Assert.AreEqual(browser1.Contexts.Count, 1);100 await browser1.CloseAsync();101 Assert.AreEqual(browser2.Contexts.Count, 1);102 var page2 = await browser2.NewPageAsync();103 Assert.AreEqual(await page2.EvaluateAsync<int>("7 * 6"), 42); // original browser should still work104 await browser2.CloseAsync();105 }106 [PlaywrightTest("browsertype-connect.spec.ts", "should timeout in connect while connecting")]107 [Skip(SkipAttribute.Targets.Windows)]108 public async Task ShouldTimeoutInConnectWhileConnecting()109 {110 var exception = await PlaywrightAssert.ThrowsAsync<TimeoutException>(async () => await BrowserType.ConnectAsync($"ws://localhost:{Server.Port}/ws", new BrowserTypeConnectOptions { Timeout = 100 }));111 StringAssert.Contains("BrowserType.ConnectAsync: Timeout 100ms exceeded", exception.Message);112 }113 [PlaywrightTest("browsertype-connect.spec.ts", "should support slowmo option")]114 public async Task ShouldSupportSlowMo()115 {116 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint, new BrowserTypeConnectOptions { SlowMo = 200 });117 var start = DateTime.Now;118 var context = await browser.NewContextAsync();119 await browser.CloseAsync();120 Assert.Greater((DateTime.Now - start).TotalMilliseconds, 199);121 }122 [PlaywrightTest("browsertype-connect.spec.ts", "disconnected event should be emitted when browser is closed or server is closed")]123 public async Task DisconnectedEventShouldBeEmittedWhenBrowserIsClosedOrServerIsClosed()124 {125 var browser1 = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);126 await browser1.NewPageAsync();127 var browser2 = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);128 await browser2.NewPageAsync();129 int disconnected1 = 0;130 int disconnected2 = 0;131 browser1.Disconnected += (_, e) => disconnected1++;132 browser2.Disconnected += (_, e) => disconnected2++;133 var tsc1 = new TaskCompletionSource<object>();134 browser1.Disconnected += (_, e) => tsc1.SetResult(null);135 await browser1.CloseAsync();136 await tsc1.Task;137 Assert.AreEqual(disconnected1, 1);138 Assert.AreEqual(disconnected2, 0);139 var tsc2 = new TaskCompletionSource<object>();140 browser2.Disconnected += (_, e) => tsc2.SetResult(null);141 await browser2.CloseAsync();142 await tsc2.Task;143 Assert.AreEqual(disconnected1, 1);144 Assert.AreEqual(disconnected2, 1);145 }146 [PlaywrightTest("browsertype-connect.spec.ts", "disconnected event should have browser as argument")]147 public async Task DisconnectedEventShouldHaveBrowserAsArguments()148 {149 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);150 IBrowser disconneced = null;151 var tsc = new TaskCompletionSource<object>();152 browser.Disconnected += (_, browser) =>153 {154 disconneced = browser;155 tsc.SetResult(null);156 };157 await browser.CloseAsync();158 await tsc.Task;159 Assert.AreEqual(browser, disconneced);160 }161 [PlaywrightTest("browsertype-connect.spec.ts", "should set the browser connected state")]162 public async Task ShouldSetTheBrowserConnectedState()163 {164 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);165 Assert.AreEqual(browser.IsConnected, true);166 var tsc = new TaskCompletionSource<bool>();167 browser.Disconnected += (_, e) => tsc.SetResult(false);168 _remoteServer.Close();169 await tsc.Task;170 Assert.AreEqual(browser.IsConnected, false);171 }172 [PlaywrightTest("browsertype-connect.spec.ts", "should throw when used after isConnected returns false")]173 public async Task ShouldThrowWhenUsedAfterIsConnectedReturnsFalse()174 {175 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);176 var page = await browser.NewPageAsync();177 var tsc = new TaskCompletionSource<bool>();178 browser.Disconnected += (_, e) => tsc.SetResult(false);179 _remoteServer.Close();180 await tsc.Task;181 Assert.AreEqual(browser.IsConnected, false);182 var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(async () => await page.EvaluateAsync("1 + 1"));183 StringAssert.Contains("has been closed", exception.Message);184 }185 [PlaywrightTest("browsertype-connect.spec.ts", "should throw when calling waitForNavigation after disconnect")]186 public async Task ShouldThrowWhenWhenCallingWaitForNavigationAfterDisconnect()187 {188 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);189 var page = await browser.NewPageAsync();190 var tsc = new TaskCompletionSource<bool>();191 browser.Disconnected += (_, e) => tsc.SetResult(false);192 _remoteServer.Close();193 await tsc.Task;194 Assert.AreEqual(browser.IsConnected, false);195 var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(async () => await page.WaitForNavigationAsync());196 StringAssert.Contains("Navigation failed because page was closed", exception.Message);197 }198 [PlaywrightTest("browsertype-connect.spec.ts", "should reject navigation when browser closes")]199 public async Task ShouldRejectNavigationWhenBrowserCloses()200 {201 Server.SetRoute("/one-style.css", context =>202 {203 context.Response.Redirect("/one-style.css");204 return Task.CompletedTask;205 });206 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);207 var page = await browser.NewPageAsync();208 var PageGoto = page.GotoAsync(Server.Prefix + "/one-style.html", new PageGotoOptions { Timeout = 60000 });209 await Server.WaitForRequest("/one-style.css");210 await browser.CloseAsync();211 Assert.AreEqual(browser.IsConnected, false);212 var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(async () => await PageGoto);213 StringAssert.Contains("has been closed", exception.Message);214 }215 [PlaywrightTest("browsertype-connect.spec.ts", "should reject waitForSelector when browser closes")]216 public async Task ShouldRejectWaitForSelectorWhenBrowserCloses()217 {218 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);219 var page = await browser.NewPageAsync();220 var watchdog = page.WaitForSelectorAsync("div");221 await browser.CloseAsync();222 var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(async () => await watchdog);223 Assert.That(exception.Message, Contains.Substring("has been closed"));224 }225 [PlaywrightTest("browsertype-connect.spec.ts", "should emit close events on pages and contexts")]226 public async Task ShouldEmitCloseEventsOnPagesAndContexts()227 {228 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);229 var context = await browser.NewContextAsync();230 var tsc = new TaskCompletionSource<object>();231 context.Close += (_, e) => tsc.SetResult(null);232 var page = await context.NewPageAsync();233 bool pageClosed = false;234 page.Close += (_, e) => pageClosed = true;235 _remoteServer.Close();236 await tsc.Task;237 Assert.AreEqual(pageClosed, true);238 }239 [PlaywrightTest("browsertype-connect.spec.ts", "should terminate network waiters")]240 public async Task ShouldTerminateNetworkWaiters()241 {242 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);243 var page = await browser.NewPageAsync();244 var requestWatchdog = page.WaitForRequestAsync(Server.EmptyPage);245 var responseWatchog = page.WaitForResponseAsync(Server.EmptyPage);246 _remoteServer.Close();247 async Task CheckTaskHasException(Task task)248 {249 var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(async () => await task);250 StringAssert.Contains("Page closed", exception.Message);251 StringAssert.DoesNotContain("Timeout", exception.Message);252 }253 await CheckTaskHasException(requestWatchdog);254 await CheckTaskHasException(responseWatchog);255 }256 [PlaywrightTest("browsertype-connect.spec.ts", "should not throw on close after disconnect")]257 public async Task ShouldNotThrowOnCloseAfterDisconnect()258 {259 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);260 var page = await browser.NewPageAsync();261 var tcs = new TaskCompletionSource<bool>();262 browser.Disconnected += (_, e) => tcs.SetResult(true);263 _remoteServer.Close();264 await tcs.Task;265 await browser.CloseAsync();266 }267 [PlaywrightTest("browsertype-connect.spec.ts", "should not throw on context.close after disconnect")]268 public async Task ShouldNotThrowOnContextCloseAfterDisconnect()269 {270 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);271 var context = await browser.NewContextAsync();272 await context.NewPageAsync();273 var tcs = new TaskCompletionSource<bool>();274 browser.Disconnected += (_, e) => tcs.SetResult(true);275 _remoteServer.Close();276 await tcs.Task;277 await context.CloseAsync();278 }279 [PlaywrightTest("browsertype-connect.spec.ts", "should not throw on page.close after disconnect")]280 public async Task ShouldNotThrowOnPageCloseAfterDisconnect()281 {282 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);283 var context = await browser.NewContextAsync();284 var page = await context.NewPageAsync();285 var tcs = new TaskCompletionSource<bool>();286 browser.Disconnected += (_, e) => tcs.SetResult(true);287 _remoteServer.Close();288 await tcs.Task;289 await page.CloseAsync();290 }291 [PlaywrightTest("browsertype-connect.spec.ts", "should saveAs videos from remote browser")]292 public async Task ShouldSaveAsVideosFromRemoteBrowser()293 {294 using var tempDirectory = new TempDirectory();295 var videoPath = tempDirectory.Path;296 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);297 var context = await browser.NewContextAsync(new()298 {299 RecordVideoDir = videoPath,300 RecordVideoSize = new() { Height = 320, Width = 240 }301 });302 var page = await context.NewPageAsync();303 await page.EvaluateAsync("() => document.body.style.backgroundColor = 'red'");304 await Task.Delay(1000);305 await context.CloseAsync();306 var videoSavePath = tempDirectory.Path + "my-video.webm";307 await page.Video.SaveAsAsync(videoSavePath);308 Assert.That(videoSavePath, Does.Exist);309 var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(async () => await page.Video.PathAsync());310 StringAssert.Contains("Path is not available when connecting remotely. Use SaveAsAsync() to save a local copy", exception.Message);311 }312 [PlaywrightTest("browsertype-connect.spec.ts", "should save download")]313 public async Task ShouldSaveDownload()314 {315 Server.SetRoute("/download", context =>316 {317 context.Response.Headers["Content-Type"] = "application/octet-stream";318 context.Response.Headers["Content-Disposition"] = "attachment";319 return context.Response.WriteAsync("Hello world");320 });321 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);322 var page = await browser.NewPageAsync(new() { AcceptDownloads = true });323 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");324 var downloadTask = page.WaitForDownloadAsync();325 await TaskUtils.WhenAll(326 downloadTask,327 page.ClickAsync("a"));328 using var tmpDir = new TempDirectory();329 string userPath = Path.Combine(tmpDir.Path, "these", "are", "directories", "download.txt");330 var download = downloadTask.Result;331 await download.SaveAsAsync(userPath);332 Assert.True(new FileInfo(userPath).Exists);333 Assert.AreEqual("Hello world", File.ReadAllText(userPath));334 var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => download.PathAsync());335 Assert.AreEqual("Path is not available when connecting remotely. Use SaveAsAsync() to save a local copy.", exception.Message);336 await browser.CloseAsync();337 }338 [PlaywrightTest("browsertype-connect.spec.ts", "should error when saving download after deletion")]339 public async Task ShouldErrorWhenSavingDownloadAfterDeletion()340 {341 Server.SetRoute("/download", context =>342 {343 context.Response.Headers["Content-Type"] = "application/octet-stream";344 context.Response.Headers["Content-Disposition"] = "attachment";345 return context.Response.WriteAsync("Hello world");346 });347 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);348 var page = await browser.NewPageAsync(new() { AcceptDownloads = true });349 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");350 var downloadTask = page.WaitForDownloadAsync();351 await TaskUtils.WhenAll(352 downloadTask,353 page.ClickAsync("a"));354 using var tmpDir = new TempDirectory();355 string userPath = Path.Combine(tmpDir.Path, "download.txt");356 var download = downloadTask.Result;357 await download.DeleteAsync();358 var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => download.SaveAsAsync(userPath));359 StringAssert.Contains("Target page, context or browser has been closed", exception.Message);360 await browser.CloseAsync();361 }362 [PlaywrightTest("browsertype-connect.spec.ts", "should save har")]363 public async Task ShouldSaveHar()364 {365 using var tempDirectory = new TempDirectory();366 var harPath = tempDirectory.Path + "/test.har";367 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);368 var context = await browser.NewContextAsync(new()369 {370 RecordHarPath = harPath371 });372 var page = await context.NewPageAsync();373 await page.GotoAsync(Server.EmptyPage);374 await context.CloseAsync();375 await browser.CloseAsync();376 Assert.That(harPath, Does.Exist);377 var logString = System.IO.File.ReadAllText(harPath);378 StringAssert.Contains(Server.EmptyPage, logString);379 }380 [PlaywrightTest("browsertype-connect.spec.ts", "should record trace with sources")]381 public async Task ShouldRecordContextTraces()382 {383 using var tempDirectory = new TempDirectory();384 var tracePath = tempDirectory.Path + "/trace.zip";385 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);386 var context = await browser.NewContextAsync();387 var page = await context.NewPageAsync();388 await context.Tracing.StartAsync(new() { Sources = true });389 await page.GotoAsync(Server.EmptyPage);390 await page.SetContentAsync("<button>Click</button>");391 await page.ClickAsync("button");392 await context.Tracing.StopAsync(new TracingStopOptions { Path = tracePath });393 await browser.CloseAsync();394 Assert.That(tracePath, Does.Exist);395 ZipFile.ExtractToDirectory(tracePath, tempDirectory.Path);396 Assert.That(tempDirectory.Path + "/trace.trace", Does.Exist);397 Assert.That(tempDirectory.Path + "/trace.network", Does.Exist);398 Assert.AreEqual(1, Directory.GetFiles(Path.Join(tempDirectory.Path, "resources"), "*.txt").Length);399 }400 [PlaywrightTest("browsertype-connect.spec.ts", "should upload large file")]401 [Skip(SkipAttribute.Targets.Firefox, SkipAttribute.Targets.Webkit)]402 public async Task ShouldUploadLargeFile()403 {404 var browser = await BrowserType.ConnectAsync(_remoteServer.WSEndpoint);405 var context = await browser.NewContextAsync();406 var page = await context.NewPageAsync();407 await page.GotoAsync(Server.Prefix + "/input/fileupload.html");408 using var tmpDir = new TempDirectory();409 var filePath = Path.Combine(tmpDir.Path, "200MB");410 using (var stream = File.OpenWrite(filePath))411 {412 var str = new string('a', 4 * 1024);413 for (var i = 0; i < 50 * 1024; i++)414 {415 await stream.WriteAsync(Encoding.UTF8.GetBytes(str));416 }417 }418 var input = page.Locator("input[type=file]");419 var events = await input.EvaluateHandleAsync(@"e => {420 const events = [];421 e.addEventListener('input', () => events.push('input'));422 e.addEventListener('change', () => events.push('change'));423 return events;424 }");425 await input.SetInputFilesAsync(filePath);426 Assert.AreEqual(await input.EvaluateAsync<string>("e => e.files[0].name"), "200MB");427 Assert.AreEqual(await events.EvaluateAsync<string[]>("e => e"), new[] { "input", "change" });428 var (file0Name, file0Size) = await TaskUtils.WhenAll(429 Server.WaitForRequest("/upload", request => (request.Form.Files[0].FileName, request.Form.Files[0].Length)),430 page.ClickAsync("input[type=submit]")431 );432 Assert.AreEqual("200MB", file0Name);433 Assert.AreEqual(200 * 1024 * 1024, file0Size);434 }435 private class RemoteServer436 {437 private Process Process { get; set; }438 public string WSEndpoint { get; set; }439 internal RemoteServer(string browserName)440 {441 try442 {443 var startInfo = new ProcessStartInfo(Driver.GetExecutablePath(), $"launch-server --browser {browserName}")444 {445 UseShellExecute = false,446 RedirectStandardOutput = true,447 };448 foreach (var pair in Driver.GetEnvironmentVariables())449 {450 startInfo.EnvironmentVariables[pair.Key] = pair.Value;451 }452 Process = new()453 {454 StartInfo = startInfo,455 };456 Process.Start();457 WSEndpoint = Process.StandardOutput.ReadLine();458 if (WSEndpoint != null && !WSEndpoint.StartsWith("ws://"))459 {460 throw new PlaywrightException("Invalid web socket address: " + WSEndpoint);461 }462 }463 catch (IOException ex)464 {465 throw new PlaywrightException("Failed to launch server", ex);466 }467 }468 internal void Close()469 {470 Process.Kill(true);471 Process.WaitForExit();472 WSEndpoint = null;473 }474 }475 }476}...
DownloadTests.cs
Source:DownloadTests.cs
...108 string userPath = Path.Combine(tmpDir.Path, "download.txt");109 await download.SaveAsAsync(userPath);110 Assert.True(new FileInfo(userPath).Exists);111 Assert.AreEqual("Hello world", File.ReadAllText(userPath));112 await page.CloseAsync();113 }114 [PlaywrightTest("download.spec.ts", "should save to user-specified path without updating original path")]115 public async Task ShouldSaveToUserSpecifiedPathWithoutUpdatingOriginalPath()116 {117 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });118 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");119 var download = await page.RunAndWaitForDownloadAsync(async () =>120 {121 await page.ClickAsync("a");122 });123 using var tmpDir = new TempDirectory();124 string userPath = Path.Combine(tmpDir.Path, "download.txt");125 await download.SaveAsAsync(userPath);126 Assert.True(new FileInfo(userPath).Exists);127 Assert.AreEqual("Hello world", File.ReadAllText(userPath));128 string originalPath = await download.PathAsync();129 Assert.True(new FileInfo(originalPath).Exists);130 Assert.AreEqual("Hello world", File.ReadAllText(originalPath));131 await page.CloseAsync();132 }133 [PlaywrightTest("download.spec.ts", "should save to two different paths with multiple saveAs calls")]134 public async Task ShouldSaveToTwoDifferentPathsWithMultipleSaveAsCalls()135 {136 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });137 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");138 var download = await page.RunAndWaitForDownloadAsync(async () =>139 {140 await page.ClickAsync("a");141 });142 using var tmpDir = new TempDirectory();143 string userPath = Path.Combine(tmpDir.Path, "download.txt");144 await download.SaveAsAsync(userPath);145 Assert.True(new FileInfo(userPath).Exists);146 Assert.AreEqual("Hello world", File.ReadAllText(userPath));147 string anotherUserPath = Path.Combine(tmpDir.Path, "download (2).txt");148 await download.SaveAsAsync(anotherUserPath);149 Assert.True(new FileInfo(anotherUserPath).Exists);150 Assert.AreEqual("Hello world", File.ReadAllText(anotherUserPath));151 await page.CloseAsync();152 }153 [PlaywrightTest("download.spec.ts", "should save to overwritten filepath")]154 public async Task ShouldSaveToOverwrittenFilepath()155 {156 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });157 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");158 var downloadTask = page.WaitForDownloadAsync();159 await TaskUtils.WhenAll(160 downloadTask,161 page.ClickAsync("a"));162 using var tmpDir = new TempDirectory();163 string userPath = Path.Combine(tmpDir.Path, "download.txt");164 var download = downloadTask.Result;165 await download.SaveAsAsync(userPath);166 Assert.AreEqual(1, new DirectoryInfo(tmpDir.Path).GetFiles().Length);167 await download.SaveAsAsync(userPath);168 Assert.AreEqual(1, new DirectoryInfo(tmpDir.Path).GetFiles().Length);169 await page.CloseAsync();170 }171 [PlaywrightTest("download.spec.ts", "should create subdirectories when saving to non-existent user-specified path")]172 public async Task ShouldCreateSubdirectoriesWhenSavingToNonExistentUserSpecifiedPath()173 {174 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });175 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");176 var downloadTask = page.WaitForDownloadAsync();177 await TaskUtils.WhenAll(178 downloadTask,179 page.ClickAsync("a"));180 using var tmpDir = new TempDirectory();181 string userPath = Path.Combine(tmpDir.Path, "these", "are", "directories", "download.txt");182 var download = downloadTask.Result;183 await download.SaveAsAsync(userPath);184 Assert.True(new FileInfo(userPath).Exists);185 Assert.AreEqual("Hello world", File.ReadAllText(userPath));186 await page.CloseAsync();187 }188 [PlaywrightTest("download.spec.ts", "should error when saving with downloads disabled")]189 public async Task ShouldErrorWhenSavingWithDownloadsDisabled()190 {191 var page = await Browser.NewPageAsync(new() { AcceptDownloads = false });192 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");193 var downloadTask = page.WaitForDownloadAsync();194 await TaskUtils.WhenAll(195 downloadTask,196 page.ClickAsync("a"));197 using var tmpDir = new TempDirectory();198 string userPath = Path.Combine(tmpDir.Path, "download.txt");199 var download = downloadTask.Result;200 var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => download.SaveAsAsync(userPath));201 StringAssert.Contains("Pass { acceptDownloads: true } when you are creating your browser context", exception.Message);202 }203 [PlaywrightTest("download.spec.ts", "should error when saving after deletion")]204 public async Task ShouldErrorWhenSavingAfterDeletion()205 {206 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });207 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");208 var downloadTask = page.WaitForDownloadAsync();209 await TaskUtils.WhenAll(210 downloadTask,211 page.ClickAsync("a"));212 using var tmpDir = new TempDirectory();213 string userPath = Path.Combine(tmpDir.Path, "download.txt");214 var download = downloadTask.Result;215 await download.DeleteAsync();216 var exception = await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => download.SaveAsAsync(userPath));217 StringAssert.Contains("Target page, context or browser has been closed", exception.Message);218 }219 [PlaywrightTest("download.spec.ts", "should report non-navigation downloads")]220 public async Task ShouldReportNonNavigationDownloads()221 {222 Server.SetRoute("/download", context =>223 {224 context.Response.Headers["Content-Type"] = "application/octet-stream";225 return context.Response.WriteAsync("Hello world");226 });227 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });228 await page.GotoAsync(Server.EmptyPage);229 await page.SetContentAsync($"<a download=\"file.txt\" href=\"{Server.Prefix}/download\">download</a>");230 var downloadTask = page.WaitForDownloadAsync();231 await TaskUtils.WhenAll(232 downloadTask,233 page.ClickAsync("a"));234 var download = downloadTask.Result;235 Assert.AreEqual("file.txt", download.SuggestedFilename);236 string path = await download.PathAsync();237 Assert.True(new FileInfo(path).Exists);238 Assert.AreEqual("Hello world", File.ReadAllText(path));239 await page.CloseAsync();240 }241 [PlaywrightTest("download.spec.ts", "should report download path within page.on('download', â¦) handler for Files")]242 public async Task ShouldReportDownloadPathWithinPageOnDownloadHandlerForFiles()243 {244 var downloadPathTcs = new TaskCompletionSource<string>();245 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });246 page.Download += async (_, e) =>247 {248 downloadPathTcs.TrySetResult(await e.PathAsync());249 };250 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");251 await page.ClickAsync("a");252 string path = await downloadPathTcs.Task;253 Assert.AreEqual("Hello world", File.ReadAllText(path));254 await page.CloseAsync();255 }256 [PlaywrightTest("download.spec.ts", "should report download path within page.on('download', â¦) handler for Blobs")]257 public async Task ShouldReportDownloadPathWithinPageOnDownloadHandlerForBlobs()258 {259 var downloadPathTcs = new TaskCompletionSource<string>();260 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });261 page.Download += async (_, e) =>262 {263 downloadPathTcs.TrySetResult(await e.PathAsync());264 };265 await page.GotoAsync(Server.Prefix + "/download-blob.html");266 await page.ClickAsync("a");267 string path = await downloadPathTcs.Task;268 Assert.AreEqual("Hello world", File.ReadAllText(path));269 await page.CloseAsync();270 }271 [PlaywrightTest("download.spec.ts", "should report alt-click downloads")]272 [Skip(SkipAttribute.Targets.Firefox, SkipAttribute.Targets.Webkit)]273 public async Task ShouldReportAltClickDownloads()274 {275 Server.SetRoute("/download", context =>276 {277 context.Response.Headers["Content-Type"] = "application/octet-stream";278 return context.Response.WriteAsync("Hello world");279 });280 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });281 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");282 var downloadTask = page.WaitForDownloadAsync();283 await TaskUtils.WhenAll(284 downloadTask,285 page.ClickAsync("a", new() { Modifiers = new[] { KeyboardModifier.Alt } }));286 var download = downloadTask.Result;287 string path = await download.PathAsync();288 Assert.True(new FileInfo(path).Exists);289 Assert.AreEqual("Hello world", File.ReadAllText(path));290 }291 [PlaywrightTest("download.spec.ts", "should report new window downloads")]292 public async Task ShouldReportNewWindowDownloads()293 {294 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });295 await page.SetContentAsync($"<a target=_blank href=\"{Server.Prefix}/download\">download</a>");296 var downloadTask = page.WaitForDownloadAsync();297 await TaskUtils.WhenAll(298 downloadTask,299 page.ClickAsync("a"));300 var download = downloadTask.Result;301 string path = await download.PathAsync();302 Assert.True(new FileInfo(path).Exists);303 Assert.AreEqual("Hello world", File.ReadAllText(path));304 }305 [PlaywrightTest("download.spec.ts", "should delete file")]306 public async Task ShouldDeleteFile()307 {308 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });309 await page.SetContentAsync($"<a target=_blank href=\"{Server.Prefix}/download\">download</a>");310 var downloadTask = page.WaitForDownloadAsync();311 await TaskUtils.WhenAll(312 downloadTask,313 page.ClickAsync("a"));314 var download = downloadTask.Result;315 string path = await download.PathAsync();316 Assert.True(new FileInfo(path).Exists);317 await download.DeleteAsync();318 Assert.False(new FileInfo(path).Exists);319 await page.CloseAsync();320 }321 [PlaywrightTest("download.spec.ts", "should expose stream")]322 public async Task ShouldExposeStream()323 {324 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });325 await page.SetContentAsync($"<a target=_blank href=\"{Server.Prefix}/downloadLarge\">download</a>");326 var downloadTask = page.WaitForDownloadAsync();327 await TaskUtils.WhenAll(328 downloadTask,329 page.ClickAsync("a"));330 var download = downloadTask.Result;331 var expected = string.Empty;332 for (var i = 0; i < 10_000; i++)333 {334 expected += $"a{i}";335 }336 using (var stream = await download.CreateReadStreamAsync())337 {338 Assert.AreEqual(expected, await new StreamReader(stream).ReadToEndAsync());339 }340 await page.CloseAsync();341 }342 [PlaywrightTest("download.spec.ts", "should delete downloads on context destruction")]343 public async Task ShouldDeleteDownloadsOnContextDestruction()344 {345 var page = await Browser.NewPageAsync(new() { AcceptDownloads = true });346 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");347 var download1Task = page.WaitForDownloadAsync();348 await TaskUtils.WhenAll(349 download1Task,350 page.ClickAsync("a"));351 var download2Task = page.WaitForDownloadAsync();352 await TaskUtils.WhenAll(353 download2Task,354 page.ClickAsync("a"));355 string path1 = await download1Task.Result.PathAsync();356 string path2 = await download2Task.Result.PathAsync();357 Assert.True(new FileInfo(path1).Exists);358 Assert.True(new FileInfo(path2).Exists);359 await page.Context.CloseAsync();360 Assert.False(new FileInfo(path1).Exists);361 Assert.False(new FileInfo(path2).Exists);362 }363 [PlaywrightTest("download.spec.ts", "should delete downloads on browser gone")]364 public async Task ShouldDeleteDownloadsOnBrowserGone()365 {366 var browser = await BrowserType.LaunchAsync();367 var page = await browser.NewPageAsync(new() { AcceptDownloads = true });368 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");369 var download1Task = page.WaitForDownloadAsync();370 await TaskUtils.WhenAll(371 download1Task,372 page.ClickAsync("a"));373 var download2Task = page.WaitForDownloadAsync();374 await TaskUtils.WhenAll(375 download2Task,376 page.ClickAsync("a"));377 string path1 = await download1Task.Result.PathAsync();378 string path2 = await download2Task.Result.PathAsync();379 Assert.True(new FileInfo(path1).Exists);380 Assert.True(new FileInfo(path2).Exists);381 await browser.CloseAsync();382 Assert.False(new FileInfo(path1).Exists);383 Assert.False(new FileInfo(path2).Exists);384 Assert.False(new FileInfo(Path.Combine(path1, "..")).Exists);385 }386 [PlaywrightTest("download.spec.ts", "should be able to cancel pending downloads")]387 public async Task ShouldBeAbleToCancelPendingDownload()388 {389 var browser = await BrowserType.LaunchAsync();390 var page = await browser.NewPageAsync(new() { AcceptDownloads = true });391 await page.SetContentAsync($"<a href=\"{Server.Prefix}/downloadWithDelay\">download</a>");392 var download = await page.RunAndWaitForDownloadAsync(() => page.ClickAsync("a"));393 await download.CancelAsync();394 var failure = await download.FailureAsync();395 Assert.AreEqual("canceled", failure);396 await page.CloseAsync();397 }398 [PlaywrightTest("download.spec.ts", "should not fail explicitly to cancel a download even if that is already finished")]399 public async Task ShouldNotFailWhenCancellingACompletedDownload()400 {401 var browser = await BrowserType.LaunchAsync();402 var page = await browser.NewPageAsync(new() { AcceptDownloads = true });403 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");404 var download = await page.RunAndWaitForDownloadAsync(() => page.ClickAsync("a"));405 using var tmpDir = new TempDirectory();406 string userPath = Path.Combine(tmpDir.Path, "download.txt");407 await download.SaveAsAsync(userPath);408 Assert.IsTrue(File.Exists(userPath));409 await download.CancelAsync();410 var failure = await download.FailureAsync();411 Assert.IsNull(failure);412 await page.CloseAsync();413 }414 [PlaywrightTest("download.spec.ts", "should report downloads with interception")]415 public async Task ShouldReportDownloadsWithInterception()416 {417 var browser = await BrowserType.LaunchAsync();418 var page = await browser.NewPageAsync(new() { AcceptDownloads = true });419 await page.RouteAsync("*", r => r.ContinueAsync());420 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");421 var download = await page.RunAndWaitForDownloadAsync(() => page.ClickAsync("a"));422 var path = await download.PathAsync();423 Assert.IsTrue(File.Exists(path));424 await page.CloseAsync();425 }426 }427}...
Connection.cs
Source:Connection.cs
...58 DefaultJsonSerializerOptions.Converters.Add(new ChannelOwnerListToGuidListConverter<WritableStream>(this));59 }60 /// <inheritdoc cref="IDisposable.Dispose"/>61 ~Connection() => Dispose(false);62 internal event EventHandler<string> Close;63 public ConcurrentDictionary<string, IChannelOwner> Objects { get; } = new();64 internal AsyncLocal<List<ApiZone>> ApiZone { get; } = new();65 public bool IsClosed { get; private set; }66 internal bool IsRemote { get; set; }67 internal Func<object, Task> OnMessage { get; set; }68 internal JsonSerializerOptions DefaultJsonSerializerOptions { get; }69 public void Dispose()70 {71 Dispose(true);72 GC.SuppressFinalize(this);73 }74 internal Task<JsonElement?> SendMessageToServerAsync(75 string guid,76 string method,77 object args = null)78 => SendMessageToServerAsync<JsonElement?>(guid, method, args);79 internal Task<T> SendMessageToServerAsync<T>(80 string guid,81 string method,82 object args = null) => WrapApiCallAsync(() => InnerSendMessageToServerAsync<T>(guid, method, args));83 private async Task<T> InnerSendMessageToServerAsync<T>(84 string guid,85 string method,86 object args = null)87 {88 if (IsClosed)89 {90 throw new PlaywrightException($"Connection closed ({_reason})");91 }92 int id = Interlocked.Increment(ref _lastId);93 var tcs = new TaskCompletionSource<JsonElement?>(TaskCreationOptions.RunContinuationsAsynchronously);94 var callback = new ConnectionCallback95 {96 TaskCompletionSource = tcs,97 };98 _callbacks.TryAdd(id, callback);99 var sanitizedArgs = new Dictionary<string, object>();100 if (args != null)101 {102 if (args is IDictionary<string, object> dictionary && dictionary.Keys.Any(f => f != null))103 {104 foreach (var kv in dictionary)105 {106 if (kv.Value != null)107 {108 sanitizedArgs.Add(kv.Key, kv.Value);109 }110 }111 }112 else113 {114 foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(args))115 {116 object obj = propertyDescriptor.GetValue(args);117 if (obj != null)118 {119#pragma warning disable CA1845 // Use span-based 'string.Concat' and 'AsSpan' instead of 'Substring120 string name = propertyDescriptor.Name.Substring(0, 1).ToLower() + propertyDescriptor.Name.Substring(1);121#pragma warning restore CA2000 // Use span-based 'string.Concat' and 'AsSpan' instead of 'Substring122 sanitizedArgs.Add(name, obj);123 }124 }125 }126 }127 await _queue.EnqueueAsync(() =>128 {129 var message = new MessageRequest130 {131 Id = id,132 Guid = guid,133 Method = method,134 Params = sanitizedArgs,135 Metadata = ApiZone.Value[0],136 };137 TraceMessage("pw:channel:command", message);138 return OnMessage(message);139 }).ConfigureAwait(false);140 var result = await tcs.Task.ConfigureAwait(false);141 if (typeof(T) == typeof(JsonElement?))142 {143 return (T)(object)result?.Clone();144 }145 else if (result == null)146 {147 return default;148 }149 else if (typeof(ChannelBase).IsAssignableFrom(typeof(T)) || typeof(ChannelBase[]).IsAssignableFrom(typeof(T)))150 {151 var enumerate = result.Value.EnumerateObject();152 return enumerate.Any()153 ? enumerate.FirstOrDefault().Value.ToObject<T>(DefaultJsonSerializerOptions)154 : default;155 }156 else157 {158 return result.Value.ToObject<T>(DefaultJsonSerializerOptions);159 }160 }161 internal IChannelOwner GetObject(string guid)162 {163 Objects.TryGetValue(guid, out var result);164 return result;165 }166 internal void MarkAsRemote() => IsRemote = true;167 internal Task<PlaywrightImpl> InitializePlaywrightAsync()168 {169 return _rootObject.InitializeAsync();170 }171 internal void OnObjectCreated(string guid, IChannelOwner result)172 {173 Objects.TryAdd(guid, result);174 }175 internal void Dispatch(PlaywrightServerMessage message)176 {177 if (message.Id.HasValue)178 {179 TraceMessage("pw:channel:response", message);180 if (_callbacks.TryRemove(message.Id.Value, out var callback))181 {182 if (message.Error != null)183 {184 callback.TaskCompletionSource.TrySetException(CreateException(message.Error.Error));185 }186 else187 {188 callback.TaskCompletionSource.TrySetResult(message.Result);189 }190 }191 return;192 }193 TraceMessage("pw:channel:event", message);194 try195 {196 if (message.Method == "__create__")197 {198 var createObjectInfo = message.Params.Value.ToObject<CreateObjectInfo>(DefaultJsonSerializerOptions);199 CreateRemoteObject(message.Guid, createObjectInfo.Type, createObjectInfo.Guid, createObjectInfo.Initializer);200 return;201 }202 if (message.Method == "__dispose__")203 {204 Objects.TryGetValue(message.Guid, out var disableObject);205 disableObject?.DisposeOwner();206 return;207 }208 Objects.TryGetValue(message.Guid, out var obj);209 obj?.Channel?.OnMessage(message.Method, message.Params);210 }211 catch (Exception ex)212 {213 DoClose(ex);214 }215 }216 private void CreateRemoteObject(string parentGuid, ChannelOwnerType type, string guid, JsonElement? initializer)217 {218 IChannelOwner result = null;219 var parent = string.IsNullOrEmpty(parentGuid) ? _rootObject : Objects[parentGuid];220#pragma warning disable CA2000 // Dispose objects before losing scope221 switch (type)222 {223 case ChannelOwnerType.Artifact:224 result = new Artifact(parent, guid, initializer?.ToObject<ArtifactInitializer>(DefaultJsonSerializerOptions));225 break;226 case ChannelOwnerType.BindingCall:227 result = new BindingCall(parent, guid, initializer?.ToObject<BindingCallInitializer>(DefaultJsonSerializerOptions));228 break;229 case ChannelOwnerType.Playwright:230 result = new PlaywrightImpl(parent, guid, initializer?.ToObject<PlaywrightInitializer>(DefaultJsonSerializerOptions));231 break;232 case ChannelOwnerType.Browser:233 var browserInitializer = initializer?.ToObject<BrowserInitializer>(DefaultJsonSerializerOptions);234 result = new Browser(parent, guid, browserInitializer);235 break;236 case ChannelOwnerType.BrowserType:237 var browserTypeInitializer = initializer?.ToObject<BrowserTypeInitializer>(DefaultJsonSerializerOptions);238 result = new Core.BrowserType(parent, guid, browserTypeInitializer);239 break;240 case ChannelOwnerType.BrowserContext:241 var browserContextInitializer = initializer?.ToObject<BrowserContextInitializer>(DefaultJsonSerializerOptions);242 result = new BrowserContext(parent, guid, browserContextInitializer);243 break;244 case ChannelOwnerType.ConsoleMessage:245 result = new ConsoleMessage(parent, guid, initializer?.ToObject<ConsoleMessageInitializer>(DefaultJsonSerializerOptions));246 break;247 case ChannelOwnerType.Dialog:248 result = new Dialog(parent, guid, initializer?.ToObject<DialogInitializer>(DefaultJsonSerializerOptions));249 break;250 case ChannelOwnerType.ElementHandle:251 result = new ElementHandle(parent, guid, initializer?.ToObject<ElementHandleInitializer>(DefaultJsonSerializerOptions));252 break;253 case ChannelOwnerType.Frame:254 result = new Frame(parent, guid, initializer?.ToObject<FrameInitializer>(DefaultJsonSerializerOptions));255 break;256 case ChannelOwnerType.JSHandle:257 result = new JSHandle(parent, guid, initializer?.ToObject<JSHandleInitializer>(DefaultJsonSerializerOptions));258 break;259 case ChannelOwnerType.JsonPipe:260 result = new JsonPipe(parent, guid, initializer?.ToObject<JsonPipeInitializer>(DefaultJsonSerializerOptions));261 break;262 case ChannelOwnerType.LocalUtils:263 result = new LocalUtils(parent, guid, initializer);264 break;265 case ChannelOwnerType.Page:266 result = new Page(parent, guid, initializer?.ToObject<PageInitializer>(DefaultJsonSerializerOptions));267 break;268 case ChannelOwnerType.Request:269 result = new Request(parent, guid, initializer?.ToObject<RequestInitializer>(DefaultJsonSerializerOptions));270 break;271 case ChannelOwnerType.Response:272 result = new Response(parent, guid, initializer?.ToObject<ResponseInitializer>(DefaultJsonSerializerOptions));273 break;274 case ChannelOwnerType.Route:275 result = new Route(parent, guid, initializer?.ToObject<RouteInitializer>(DefaultJsonSerializerOptions));276 break;277 case ChannelOwnerType.Worker:278 result = new Worker(parent, guid, initializer?.ToObject<WorkerInitializer>(DefaultJsonSerializerOptions));279 break;280 case ChannelOwnerType.WebSocket:281 result = new WebSocket(parent, guid, initializer?.ToObject<WebSocketInitializer>(DefaultJsonSerializerOptions));282 break;283 case ChannelOwnerType.Selectors:284 result = new Selectors(parent, guid);285 break;286 case ChannelOwnerType.SocksSupport:287 result = new SocksSupport(parent, guid);288 break;289 case ChannelOwnerType.Stream:290 result = new Stream(parent, guid);291 break;292 case ChannelOwnerType.WritableStream:293 result = new WritableStream(parent, guid);294 break;295 case ChannelOwnerType.Tracing:296 result = new Tracing(parent, guid);297 break;298 default:299 TraceMessage("pw:dotnet", "Missing type " + type);300 break;301 }302#pragma warning restore CA2000303 Objects.TryAdd(guid, result);304 OnObjectCreated(guid, result);305 }306 private void DoClose(Exception ex)307 {308 TraceMessage("pw:dotnet", $"Connection Close: {ex.Message}\n{ex.StackTrace}");309 DoClose(ex.Message);310 }311 internal void DoClose(string reason)312 {313 _reason = string.IsNullOrEmpty(_reason) ? reason : _reason;314 if (!IsClosed)315 {316 foreach (var callback in _callbacks)317 {318 callback.Value.TaskCompletionSource.TrySetException(new PlaywrightException(reason));319 }320 Dispose();321 IsClosed = true;322 }323 }324 private Exception CreateException(PlaywrightServerError error)325 {326 if (string.IsNullOrEmpty(error.Message))327 {328 return new PlaywrightException(error.Value);329 }330 if (error.Name == "TimeoutError")331 {332 return new TimeoutException(error.Message);333 }334 return new PlaywrightException(error.Message);335 }336 private void Dispose(bool disposing)337 {338 if (!disposing)339 {340 return;341 }342 _queue.Dispose();343 Close.Invoke(this, "Connection disposed");344 }345 [Conditional("DEBUG")]346 internal void TraceMessage(string logLevel, object message)347 {348 string actualLogLevel = Environment.GetEnvironmentVariable("DEBUG");349 if (!string.IsNullOrEmpty(actualLogLevel))350 {351 if (!actualLogLevel.Contains(logLevel))352 {353 return;354 }355 if (!(message is string))356 {357 message = JsonSerializer.Serialize(message, DefaultJsonSerializerOptions);...
DownloadsPathTests.cs
Source:DownloadsPathTests.cs
...44 var download = downloadTask.Result;45 Assert.AreEqual($"{Server.Prefix}/download", download.Url);46 Assert.AreEqual("file.txt", download.SuggestedFilename);47 await PlaywrightAssert.ThrowsAsync<PlaywrightException>(() => download.PathAsync());48 await page.CloseAsync();49 await _browser.CloseAsync();50 Assert.True(new DirectoryInfo(_tmp.Path).Exists);51 }52 [PlaywrightTest("downloads-path.spec.ts", "should delete downloads when context closes")]53 public async Task ShouldDeleteDownloadsWhenContextCloses()54 {55 var page = await _browser.NewPageAsync(new() { AcceptDownloads = true });56 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");57 var downloadTask = page.WaitForDownloadAsync();58 await TaskUtils.WhenAll(59 downloadTask,60 page.ClickAsync("a"));61 var download = downloadTask.Result;62 string path = await download.PathAsync();63 Assert.True(new FileInfo(path).Exists);64 await page.CloseAsync();65 Assert.False(new FileInfo(path).Exists);66 }67 [PlaywrightTest("downloads-path.spec.ts", "should report downloads in downloadsPath folder")]68 public async Task ShouldReportDownloadsInDownloadsPathFolder()69 {70 var page = await _browser.NewPageAsync(new() { AcceptDownloads = true });71 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");72 var downloadTask = page.WaitForDownloadAsync();73 await TaskUtils.WhenAll(74 downloadTask,75 page.ClickAsync("a"));76 var download = downloadTask.Result;77 string path = await download.PathAsync();78 Assert.That(path, Does.StartWith(_tmp.Path));79 await page.CloseAsync();80 }81 [PlaywrightTest("downloads-path.spec.ts", "should report downloads in downloadsPath folder with a relative path")]82 public async Task ShouldReportDownloadsInDownloadsPathFolderWithARelativePath()83 {84 var browser = await Playwright[TestConstants.BrowserName]85 .LaunchAsync(new()86 {87 DownloadsPath = "."88 });89 var page = await browser.NewPageAsync(new()90 {91 AcceptDownloads = true92 });93 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");94 var download = await page.RunAndWaitForDownloadAsync(() => page.ClickAsync("a"));95 string path = await download.PathAsync();96 Assert.That(path, Does.StartWith(Directory.GetCurrentDirectory()));97 await page.CloseAsync();98 }99 [PlaywrightTest("downloads-path.spec.ts", "should accept downloads in persistent context")]100 public async Task ShouldAcceptDownloadsInPersistentContext()101 {102 var userProfile = new TempDirectory();103 var browser = await Playwright[TestConstants.BrowserName]104 .LaunchPersistentContextAsync(userProfile.Path, new()105 {106 AcceptDownloads = true,107 DownloadsPath = _tmp.Path108 });109 var page = await browser.NewPageAsync();110 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");111 var download = await page.RunAndWaitForDownloadAsync(() => page.ClickAsync("a"));112 Assert.AreEqual($"{Server.Prefix}/download", download.Url);113 Assert.AreEqual("file.txt", download.SuggestedFilename);114 Assert.That(await download.PathAsync(), Does.StartWith(_tmp.Path));115 await page.CloseAsync();116 }117 [PlaywrightTest("downloads-path.spec.ts", "should delete downloads when persistent context closes")]118 public async Task ShouldDeleteDownloadsWhenPersistentContextCloses()119 {120 var userProfile = new TempDirectory();121 var browser = await Playwright[TestConstants.BrowserName]122 .LaunchPersistentContextAsync(userProfile.Path, new()123 {124 AcceptDownloads = true,125 DownloadsPath = _tmp.Path126 });127 var page = await browser.NewPageAsync();128 await page.SetContentAsync($"<a href=\"{Server.Prefix}/download\">download</a>");129 var download = await page.RunAndWaitForDownloadAsync(() => page.ClickAsync("a"));130 var path = await download.PathAsync();131 Assert.IsTrue(File.Exists(path));132 await browser.CloseAsync();133 Assert.IsFalse(File.Exists(path));134 }135 [SetUp]136 public async Task InitializeAsync()137 {138 Server.SetRoute("/download", context =>139 {140 context.Response.Headers["Content-Type"] = "application/octet-stream";141 context.Response.Headers["Content-Disposition"] = "attachment; filename=file.txt";142 return context.Response.WriteAsync("Hello world");143 });144 _tmp = new();145 _browser = await Playwright[TestConstants.BrowserName].LaunchAsync(new() { DownloadsPath = _tmp.Path });146 }147 [TearDown]148 public async Task DisposeAsync()149 {150 await _browser.CloseAsync();151 _tmp.Dispose();152 }153 }154}...
WritableStream.cs
Source:WritableStream.cs
...39 IChannel<WritableStream> IChannelOwner<WritableStream>.Channel => Channel;40 public WritableStreamChannel Channel { get; }41 public WritableStreamImpl WritableStreamImpl => new(this);42 public Task WriteAsync(string binary) => Channel.WriteAsync(binary);43 public ValueTask DisposeAsync() => new ValueTask(CloseAsync());44 public Task CloseAsync() => Channel.CloseAsync();45 }46 internal class WritableStreamImpl : System.IO.Stream47 {48 private readonly WritableStream _stream;49 internal WritableStreamImpl(WritableStream stream)50 {51 _stream = stream;52 }53 public override bool CanRead => throw new NotImplementedException();54 public override bool CanSeek => throw new NotImplementedException();55 public override bool CanWrite => true;56 public override long Length => throw new NotImplementedException();57 public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }58 public override void Flush() => throw new NotImplementedException();59 public override int Read(byte[] buffer, int offset, int count) => throw new NotImplementedException();60 public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>61 throw new NotImplementedException();62 public override void Close() => _stream.CloseAsync().ConfigureAwait(false);63 public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException();64 public override void SetLength(long value) => throw new NotImplementedException();65 public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException();66 public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)67 {68 await this._stream.WriteAsync(Convert.ToBase64String(buffer)).ConfigureAwait(false);69 }70 }71}...
Stream.cs
Source:Stream.cs
...39 IChannel<Stream> IChannelOwner<Stream>.Channel => Channel;40 public StreamChannel Channel { get; }41 public StreamImpl StreamImpl => new(this);42 public Task<byte[]> ReadAsync(int size) => Channel.ReadAsync(size);43 public ValueTask DisposeAsync() => new ValueTask(CloseAsync());44 public Task CloseAsync() => Channel.CloseAsync();45 }46 internal class StreamImpl : System.IO.Stream47 {48 private readonly Stream _stream;49 internal StreamImpl(Stream stream)50 {51 _stream = stream;52 }53 public override bool CanRead => true;54 public override bool CanSeek => false;55 public override bool CanWrite => throw new NotImplementedException();56 public override long Length => throw new NotImplementedException();57 public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }58 public override void Flush() => throw new NotImplementedException();59 public override int Read(byte[] buffer, int offset, int count) => throw new NotImplementedException();60 public override async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)61 {62 var result = await _stream.ReadAsync(count).ConfigureAwait(false);63 result.CopyTo(buffer, offset);64 return result.Length;65 }66 public override void Close() => _stream.CloseAsync().ConfigureAwait(false);67 public override long Seek(long offset, SeekOrigin origin) => throw new NotImplementedException();68 public override void SetLength(long value) => throw new NotImplementedException();69 public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException();70 }71}...
StreamChannel.cs
Source:StreamChannel.cs
...41 ["size"] = size,42 }).ConfigureAwait(false);43 return response.Value.GetProperty("binary").GetBytesFromBase64();44 }45 internal Task CloseAsync() => Connection.SendMessageToServerAsync(Guid, "close", null);46 }47}...
WritableStreamChannel.cs
Source:WritableStreamChannel.cs
...40 {41 ["binary"] = binary,42 }).ConfigureAwait(false);43 }44 internal Task CloseAsync() => Connection.SendMessageToServerAsync(Guid, "close", null);45 }46}...
Close
Using AI Code Generation
1using Microsoft.Playwright;2using System;3using System.Threading.Tasks;4{5 {6 static async Task Main(string[] args)7 {8 using var playwright = await Playwright.CreateAsync();9 var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions { Headless = false });10 var context = await browser.NewContextAsync();11 var page = await context.NewPageAsync();12 var stream = await page.ScreenshotStreamAsync();13 await stream.CloseAsync();14 await browser.CloseAsync();15 }16 }17}
Close
Using AI Code Generation
1using Microsoft.Playwright;2var playwright = await Playwright.CreateAsync();3var browser = await playwright.Chromium.LaunchAsync();4var page = await browser.NewPageAsync();5var stream = response.Body;6await stream.CloseAsync();7await browser.CloseAsync();8using Microsoft.Playwright;9var playwright = await Playwright.CreateAsync();10var browser = await playwright.Chromium.LaunchAsync();11var page = await browser.NewPageAsync();12var stream = response.Body;13await stream.CloseAsync();14await browser.CloseAsync();15using Microsoft.Playwright;16var playwright = await Playwright.CreateAsync();17var browser = await playwright.Chromium.LaunchAsync();18var page = await browser.NewPageAsync();19var stream = response.Body;20await stream.CloseAsync();21await browser.CloseAsync();22using Microsoft.Playwright;23var playwright = await Playwright.CreateAsync();24var browser = await playwright.Chromium.LaunchAsync();25var page = await browser.NewPageAsync();26var stream = response.Body;27await stream.CloseAsync();28await browser.CloseAsync();29using Microsoft.Playwright;30var playwright = await Playwright.CreateAsync();31var browser = await playwright.Chromium.LaunchAsync();32var page = await browser.NewPageAsync();33var stream = response.Body;34await stream.CloseAsync();35await browser.CloseAsync();36using Microsoft.Playwright;37var playwright = await Playwright.CreateAsync();38var browser = await playwright.Chromium.LaunchAsync();39var page = await browser.NewPageAsync();40var stream = response.Body;41await stream.CloseAsync();42await browser.CloseAsync();
Close
Using AI Code Generation
1using System;2using System.IO;3using Microsoft.Playwright;4{5 {6 static async System.Threading.Tasks.Task Main(string[] args)7 {8 using var playwright = await Playwright.CreateAsync();9 var browser = await playwright.Chromium.LaunchAsync();10 var page = await browser.NewPageAsync();11 await page.ScreenshotAsync(path: "screenshot.png");12 await page.PdfAsync(path: "screenshot.pdf");13 await page.ScreenshotAsync(path: "screenshot.jpg", type: ScreenshotType.Jpeg);14 await page.ScreenshotAsync(path: "screenshot.png", type: ScreenshotType.Png);15 await page.ScreenshotAsync(path: "screenshot.webp", type: ScreenshotType.Webp);16 await page.ScreenshotAsync(path: "screenshot.avif", type: ScreenshotType.Avif);17 await page.ScreenshotAsync(path: "screenshot.heif", type: ScreenshotType.Heif);18 await page.ScreenshotAsync(path: "screenshot.heic", type: ScreenshotType.Heic);19 await page.ScreenshotAsync(path: "screenshot.tiff", type: ScreenshotType.Tiff);20 await page.ScreenshotAsync(path: "screenshot.bmp", type: ScreenshotType.Bmp);21 await page.ScreenshotAsync(path: "screenshot.svg", type: ScreenshotType.Svg);22 await page.ScreenshotAsync(path: "screenshot
Close
Using AI Code Generation
1using Microsoft.Playwright.Core;2using System;3using System.IO;4using System.Threading.Tasks;5{6 {7 static async Task Main(string[] args)8 {9 var playwright = await Playwright.CreateAsync();10 var browser = await playwright.Chromium.LaunchAsync();11 var page = await browser.NewPageAsync();12 var stream = await response.BodyAsync();13 var buffer = new byte[1000];14 var bytesRead = await stream.ReadAsync(buffer, 0, 1000);15 Console.WriteLine($"Bytes read: {bytesRead}");16 stream.Close();17 await browser.CloseAsync();18 }19 }20}
Close
Using AI Code Generation
1var playwright = await Playwright.CreateAsync();2var browser = await playwright.Chromium.LaunchAsync();3var page = await browser.NewPageAsync();4await page.PressAsync("input[name=q]", "Enter");5var response = await page.WaitForResponseAsync("**/*");6var stream = await response.BodyAsync();7await stream.CloseAsync();8var playwright = await Playwright.CreateAsync();9var browser = await playwright.Chromium.LaunchAsync();10var page = await browser.NewPageAsync();11await page.PressAsync("input[name=q]", "Enter");12var response = await page.WaitForResponseAsync("**/*");13var stream = await response.BodyAsync();14stream.Dispose();15var playwright = await Playwright.CreateAsync();16var browser = await playwright.Chromium.LaunchAsync();17var page = await browser.NewPageAsync();18await page.PressAsync("input[name=q]", "Enter");19var response = await page.WaitForResponseAsync("**/*");20var stream = await response.BodyAsync();21await stream.CloseAsync();22var playwright = await Playwright.CreateAsync();23var browser = await playwright.Chromium.LaunchAsync();24var page = await browser.NewPageAsync();25await page.PressAsync("input[name=q]", "Enter");26var response = await page.WaitForResponseAsync("**/*");27var stream = await response.BodyAsync();28stream.Dispose();29var playwright = await Playwright.CreateAsync();30var browser = await playwright.Chromium.LaunchAsync();31var page = await browser.NewPageAsync();32await page.PressAsync("input[name=q]", "Enter");33var response = await page.WaitForResponseAsync("**/*");34var stream = await response.BodyAsync();35await stream.CloseAsync();
Close
Using AI Code Generation
1var browser = await Playwright.CreateAsync().Chromium.LaunchAsync(new LaunchOptions2{3 Args = new[] { "--start-maximized" }4});5var context = await browser.NewContextAsync();6var page = await context.NewPageAsync();7await page.ClickAsync("text=Images");8var element = await page.QuerySelectorAsync("text=Images");9await element.ClickAsync();10await page.ClickAsync("text=Imag
Close
Using AI Code Generation
1using Microsoft.Playwright;2using Microsoft.Playwright.Core;3using System.Threading.Tasks;4{5 {6 static async Task Main(string[] args)7 {8 using var playwright = await Playwright.CreateAsync();9 var browser = await playwright.Chromium.LaunchAsync(headless: false);10 var page = await browser.NewPageAsync();11 await page.PressAsync("input[title='Search']", "ArrowDown");12 await page.PressAsync("input[title='Search']", "Enter");13 var screenshot = await page.ScreenshotAsync();14 await screenshot.CloseAsync();15 await browser.CloseAsync();16 }17 }18}
Close
Using AI Code Generation
1await using var stream = await page.Video.SaveAsAsync();2await stream.CloseAsync();3await stream.DisposeAsync();4await using var stream = await page.Video.SaveAsAsync();5await stream.CloseAsync();6await stream.DisposeAsync();7await using var stream = await page.Video.SaveAsAsync();8await stream.CloseAsync();9await stream.DisposeAsync();10await using var stream = await page.Video.SaveAsAsync();11await stream.CloseAsync();12await stream.DisposeAsync();13await using var stream = await page.Video.SaveAsAsync();14await stream.CloseAsync();15await stream.DisposeAsync();16await using var stream = await page.Video.SaveAsAsync();17await stream.CloseAsync();18await stream.DisposeAsync();19await using var stream = await page.Video.SaveAsAsync();20await stream.CloseAsync();21await stream.DisposeAsync();22await using var stream = await page.Video.SaveAsAsync();23await stream.CloseAsync();24await stream.DisposeAsync();25await using var stream = await page.Video.SaveAsAsync();26await stream.CloseAsync();27await stream.DisposeAsync();28await using var stream = await page.Video.SaveAsAsync();29await stream.CloseAsync();30await stream.DisposeAsync();31await using var stream = await page.Video.SaveAsAsync();32await stream.CloseAsync();33await stream.DisposeAsync();34await using var stream = await page.Video.SaveAsAsync();35await stream.CloseAsync();36await stream.DisposeAsync();
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!