How to use Close method of Microsoft.Playwright.Transport.StdIOTransport class

Best Playwright-dotnet code snippet using Microsoft.Playwright.Transport.StdIOTransport.Close

Run Playwright-dotnet automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Playwright.cs

Source: Playwright.cs Github

copy
1/*
2 * MIT License
3 *
4 * Copyright (c) Microsoft Corporation.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25using System;
26using System.Diagnostics.CodeAnalysis;
27using System.Text.Json;
28using System.Threading.Tasks;
29using Microsoft.Playwright.Helpers;
30using Microsoft.Playwright.Transport;
31
32namespace Microsoft.Playwright
33{
34    [SuppressMessage("Microsoft.Design", "CA1724", Justification = "Playwright is the entrypoint for all languages.")]
35    public static class Playwright
36    {
37        /// <summary>
38        /// Launches Playwright.
39        /// </summary>
40        /// <returns>A <see cref="Task"/> that completes when the playwright driver is ready to be used.</returns>
41        public static async Task<IPlaywright> CreateAsync()
42        {
43#pragma warning disable CA2000 // Dispose objects before losing scope
44            var transport = new StdIOTransport();
45#pragma warning restore CA2000
46            var connection = new Connection();
47            transport.MessageReceived += (_, message) => connection.Dispatch(JsonSerializer.Deserialize<PlaywrightServerMessage>(message, JsonExtensions.DefaultJsonSerializerOptions));
48            transport.LogReceived += (_, log) => Console.Error.WriteLine(log);
49            transport.TransportClosed += (_, reason) => connection.DoClose(reason);
50            connection.OnMessage = (message) => transport.SendAsync(JsonSerializer.SerializeToUtf8Bytes(message, connection.DefaultJsonSerializerOptions));
51            connection.Close += (_, reason) => transport.Close(reason);
52            var playwright = await connection.InitializePlaywrightAsync().ConfigureAwait(false);
53            playwright.Connection = connection;
54            return playwright;
55        }
56    }
57}
58
Full Screen

StdIOTransport.cs

Source: StdIOTransport.cs Github

copy
1/*
2 * MIT License
3 *
4 * Copyright (c) Microsoft Corporation.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25using System;
26using System.Collections.Generic;
27using System.Diagnostics;
28using System.Threading;
29using System.Threading.Tasks;
30using Microsoft.Playwright.Helpers;
31
32namespace Microsoft.Playwright.Transport
33{
34    internal class StdIOTransport : IConnectionTransport, IDisposable
35    {
36        private const int DefaultBufferSize = 1024;  // Byte buffer size
37        private readonly Process _process;
38        private readonly CancellationTokenSource _readerCancellationSource = new();
39        private readonly List<byte> _data = new();
40        private int? _currentMessageSize;
41
42        internal StdIOTransport()
43        {
44            _process = GetProcess();
45            _process.StartInfo.Arguments = "run-driver";
46            _process.Start();
47            _process.Exited += (_, _) => Close("Process exited");
48            _process.ErrorDataReceived += (_, error) =>
49            {
50                if (error.Data != null)
51                {
52                    LogReceived?.Invoke(this, error.Data);
53                }
54            };
55            _process.BeginErrorReadLine();
56
57            ScheduleTransportTask(GetResponseAsync, _readerCancellationSource.Token);
58        }
59
60        /// <inheritdoc cref="IDisposable.Dispose"/>
61        ~StdIOTransport() => Dispose(false);
62
63        public event EventHandler<byte[]> MessageReceived;
64
65        public event EventHandler<string> TransportClosed;
66
67        public event EventHandler<string> LogReceived;
68
69        public bool IsClosed { get; private set; }
70
71        /// <inheritdoc/>
72        public void Dispose()
73        {
74            Dispose(true);
75            GC.SuppressFinalize(this);
76        }
77
78        /// <inheritdoc/>
79        public void Close(string closeReason)
80        {
81            if (!IsClosed)
82            {
83                IsClosed = true;
84                TransportClosed.Invoke(this, closeReason);
85                _readerCancellationSource?.Cancel();
86                _process.StandardInput.Close();
87                _process.WaitForExit();
88            }
89        }
90
91        public async Task SendAsync(byte[] message)
92        {
93            try
94            {
95                if (!_readerCancellationSource.IsCancellationRequested)
96                {
97                    int len = message.Length;
98                    byte[] ll = new byte[4];
99                    ll[0] = (byte)(len & 0xFF);
100                    ll[1] = (byte)((len >> 8) & 0xFF);
101                    ll[2] = (byte)((len >> 16) & 0xFF);
102                    ll[3] = (byte)((len >> 24) & 0xFF);
103
104#pragma warning disable CA1835 // We can't use ReadOnlyMemory on netstandard
105                    await _process.StandardInput.BaseStream.WriteAsync(ll, 0, 4, _readerCancellationSource.Token).ConfigureAwait(false);
106                    await _process.StandardInput.BaseStream.WriteAsync(message, 0, len, _readerCancellationSource.Token).ConfigureAwait(false);
107#pragma warning restore CA1835
108                    await _process.StandardInput.BaseStream.FlushAsync(_readerCancellationSource.Token).ConfigureAwait(false);
109                }
110            }
111            catch (Exception ex)
112            {
113                Close(ex);
114            }
115        }
116
117        private static Process GetProcess()
118        {
119            var startInfo = new ProcessStartInfo(Driver.GetExecutablePath())
120            {
121                UseShellExecute = false,
122                RedirectStandardOutput = true,
123                RedirectStandardInput = true,
124                RedirectStandardError = true,
125                CreateNoWindow = true,
126            };
127            foreach (var pair in Driver.GetEnvironmentVariables())
128            {
129                startInfo.EnvironmentVariables[pair.Key] = pair.Value;
130            }
131            return new()
132            {
133                StartInfo = startInfo,
134            };
135        }
136
137        private static void ScheduleTransportTask(Func<CancellationToken, Task> func, CancellationToken cancellationToken)
138            => Task.Factory.StartNew(() => func(cancellationToken), cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
139
140        private void Close(Exception ex)
141        {
142            System.Diagnostics.Debug.WriteLine(ex);
143            Close(ex.ToString());
144        }
145
146        private void Dispose(bool disposing)
147        {
148            if (!disposing)
149            {
150                return;
151            }
152
153            _readerCancellationSource?.Dispose();
154            _process?.Dispose();
155        }
156
157        private async Task GetResponseAsync(CancellationToken token)
158        {
159            try
160            {
161                var stream = _process.StandardOutput;
162                byte[] buffer = new byte[DefaultBufferSize];
163
164                while (!token.IsCancellationRequested && !_process.HasExited)
165                {
166#pragma warning disable CA1835 // We can't use ReadOnlyMemory on netstandard
167                    int read = await stream.BaseStream.ReadAsync(buffer, 0, DefaultBufferSize, token).ConfigureAwait(false);
168#pragma warning restore CA1835
169                    if (!token.IsCancellationRequested)
170                    {
171                        _data.AddRange(buffer.AsSpan(0, read).ToArray());
172
173                        ProcessStream(token);
174                    }
175                }
176            }
177            catch (Exception ex)
178            {
179                Close(ex);
180            }
181        }
182
183        private void ProcessStream(CancellationToken token)
184        {
185            while (!token.IsCancellationRequested)
186            {
187                if (_currentMessageSize == null && _data.Count < 4)
188                {
189                    break;
190                }
191
192                if (_currentMessageSize == null)
193                {
194                    _currentMessageSize = _data[0] + (_data[1] << 8) + (_data[2] << 16) + (_data[3] << 24);
195                    _data.RemoveRange(0, 4);
196                }
197
198                if (_data.Count < _currentMessageSize)
199                {
200                    break;
201                }
202
203                byte[] result = _data.GetRange(0, _currentMessageSize.Value).ToArray();
204                _data.RemoveRange(0, _currentMessageSize.Value);
205                _currentMessageSize = null;
206                MessageReceived?.Invoke(this, result);
207            }
208        }
209    }
210}
211
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Trigger Close code on LambdaTest Cloud Grid

Execute automation tests with Close on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)