I'm creating a C# program to assist me in testing websites I develop and am having some issues. The goal is to have the program store different accounts for my website along with their associated cookies so it can automatically log them in for testing. Right now I am using Playwright for the browser automation as well as the cookies storage (no issues with any of this). However, my issue seems to stem from the fact that FileSystemWatcher doesn't fire after I save my cookies.
My goal is to update my programs interface with the accounts I have saved each time I add a new one. To do this I am using the FileSystemWatcher to call a function that reloads all my user accounts from a file.
My function for creating the FileSystemWatcher looks like this:
private string filesPath = @"" + Path.GetDirectoryName(Application.ExecutablePath) + "\\inc";
private void CreateFileWatcher()
{
FileSystemWatcher fsWatcher = new FileSystemWatcher(filesPath, "accounts.dat");
fsWatcher.NotifyFilter = NotifyFilters.LastWrite;
fsWatcher.Changed += new FileSystemEventHandler((object s, FileSystemEventArgs e) =>
{
// Load accounts
});
fsWatcher.EnableRaisingEvents = true;
}
I want to specifically watch that "accounts.dat" file so I've added it as the filter as you can see from my code.
For adding a new account my function looks like this:
private void CreateAccount() {
Dictionary<Guid, Account> accounts;
Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryFormatter bf = new BinaryFormatter();
try
{
accounts = (Dictionary<Guid, Account>)bf.Deserialize(stream);
accounts.Add(account.UUID, account);
}
catch
{
accounts = new Dictionary<Guid, Account>();
accounts.Add(account.UUID, account);
}
stream.Close();
stream = new FileStream(fileName, FileMode.Truncate, FileAccess.Write);
bf.Serialize(stream, accounts);
stream.Close();
// Then I call my login function that logs the account in and saves the cookies
}
My function for logging in is:
public static Task Login(Account account, string url) {
try
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync(new()
{
Headless = false,
});
await using var context = await browser.NewContextAsync(new()
{
ViewportSize = new ViewportSize() { Height = 450, Width = 500 }
});
// Create page
var page = await context.NewPageAsync();
await page.GotoAsync(url);
// Sign in
await Login(page, account);
// Save auth state
string cookies = await context.StorageStateAsync();
// Write cookies
await WriteCookies(cookies, account);
}
catch (Exception e)
{
// Log to my logfile
}
}
And lastly, my function for saving cookies is:
public static async Task WriteCookies(string cookies, Account account) {
// Create list of accounts
Dictionary<Guid, string> sessions;
Stream stream = new FileStream(sessionsFile, FileMode.Open, FileAccess.Read);
BinaryFormatter bf = new BinaryFormatter();
try
{
sessions = (Dictionary<Guid, string>)bf.Deserialize(stream);
sessions.Add(account.UUID, cookies);
}
catch
{
sessions = new Dictionary<Guid, string>();
sessions.Add(account.UUID, cookies);
}
stream.Close();
stream = new FileStream(sessionsFile, FileMode.Truncate, FileAccess.Write);
bf.Serialize(stream, sessions);
stream.Close();
}
As you can see from my code, each session is associated to a user account via the accounts Guid
so I can easily access the correct session related to the account later. I thought the issue stemmed from the fact that my write cookies function was asynchronous so it was throwing off the FileSystemWatcher so I tried separating the sessions and accounts to fix this but have had no luck. I can't seem to figure out what I'm doing wrong but it seems like the event fires when the account is first created, then once I write the cookies it never fires again until I manually reload the form. I appreciate any help.
Also, right now I am opening the file to grab the existing data, closing it, then reopening it in Truncate
mode as I want to clear the file each time so if you recommend a better way of adding new objects to my list I would love to hear them.
Thanks!