Skip to content

[🐛 Bug]: [dotnet] Sendkeys to file input doesn't work with files with unicode character in the name on linux headless #16762

@banjand

Description

@banjand

Description

I have a test that needs to use a file with unicode character in the name called "Manuscript_Unicode_€.docx" and I need to use it to upload it to a page on the site to make sure the website supports the unicode character named files. Which works fine on windows, but on linux when I try to use the filepath to the file, it just doesn't work with the euro character in the name, it says the file file not found.
I expect the sendkeys to work with unicode characters also since the system is capable to use the characters, because it can add the character if I want to add the text to a normal input field.
Logs to see

2025-12-20 11:06:40,419 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: TestingUnicodeStuff0 - Line 82 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Constructed File Path: /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/bin/Debug/net8.0/TestData/SubmissionItems/SESMail/Manuscript_Unicode_€.docx  2025-12-20 11:06:40,419 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: TestingUnicodeStuff0 - Line 83 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] File Exists: True  2025-12-20 11:06:40,420 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 176 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Sending file path to input: /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/bin/Debug/net8.0/TestData/SubmissionItems/SESMail/Manuscript_Unicode_€.docx  2025-12-20 11:06:40,420 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 177 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] File name: Manuscript_Unicode_€.docx  2025-12-20 11:06:40,420 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 181 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Absolute path: /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/bin/Debug/net8.0/TestData/SubmissionItems/SESMail/Manuscript_Unicode_€.docx  2025-12-20 11:06:40,420 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 186 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Normalized path: /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/bin/Debug/net8.0/TestData/SubmissionItems/SESMail/Manuscript_Unicode_€.docx  2025-12-20 11:06:40,420 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 190 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Path UTF8 bytes: 2F-67-69-74-68-75-62-72-75-6E-6E-65-72-2F-5F-77-6F-72-6B-2F-65-64-69-74-6F-72-69-61-6C-6D-61-6E-61-67-65-72-2D-74-65-73-74-2D-61-75-74-6F-6D-61-74-69-6F-6E-2F-65-64-69-74-6F-72-69-61-6C-6D-61-6E-61-67-65-72-2D-74-65-73-74-2D-61-75-74-6F-6D-61-74-69-6F-6E-2F-46-65-61-74-75-72-65-54-65-73-74-73-2F-62-69-6E-2F-44-65-62-75-67-2F-6E-65-74-38-2E-30-2F-54-65-73-74-44-61-74-61-2F-53-75-62-6D-69-73-73-69-6F-6E-49-74-65-6D-73-2F-53-45-53-4D-61-69-6C-2F-4D-61-6E-75-73-63-72-69-70-74-5F-55-6E-69-63-6F-64-65-5F-E2-82-AC-2E-64-6F-63-78  2025-12-20 11:06:40,455 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 204 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] WebDriver 'File not found' error - this indicates a Selenium/ChromeDriver Unicode handling issue  2025-12-20 11:06:40,456 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 205 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Error message: invalid argument: File not found
Note: I've been trying different workarounds but it feels like this should work out of the box.

Reproducible Code

[TestMethod]
    public void TestingUnicodeStuff0()
    {
        // Navigate to your webpage
        Browsers.Goto("https://the-internet.herokuapp.com/upload");

        // Build the file path using platform-agnostic Path.Combine
        string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
        string[] pathSegments = { baseDirectory, "TestData", "SubmissionItems", "SESMail", "Manuscript_Unicode_€.docx" };
        string filePath = Path.Combine(pathSegments);

        // Log the file path for debugging
        Log.Info($"Base Directory: {baseDirectory}");
        Log.Info($"Constructed File Path: {filePath}");
        Log.Info($"File Exists: {File.Exists(filePath)}");

        // If file doesn't exist, check for alternative file names
        if (!File.Exists(filePath))
        {
            Log.Info($"File not found at: {filePath}");
            Log.Info("Checking for alternative file names in the directory...");
            
            string testDataDir = Path.Combine(baseDirectory, "TestData", "Submission Items", "SESMail");
            if (Directory.Exists(testDataDir))
            {
                var files = Directory.GetFiles(testDataDir, "Manuscript_Unicode*");
                Log.Info($"Found {files.Length} matching files:");
                foreach (var file in files)
                {
                    Log.Info($"  - {file}");
                }
                
                if (files.Length > 0)
                {
                    filePath = files[0];
                    Log.Info($"Using first matching file: {filePath}");
                }
            }
            else
            {
                Log.Error($"Test data directory not found: {testDataDir}");
                Assert.Fail($"Test data directory does not exist: {testDataDir}");
            }
        }

        // Verify file exists before attempting upload
        Assert.IsTrue(File.Exists(filePath), $"File not found: {filePath}");

        // Send the file path to the input element
        // Use platform-specific workaround for Unicode filename handling
        bool uploadSuccess = SendFilePathToInputWithUnicodeSupport(filePath);
        Assert.IsTrue(uploadSuccess, "Failed to send file path to upload input");

        // Optionally, trigger the upload button
        var uploadButton = Browsers.getDriver.FindElement(By.XPath("//input[@id='file-submit']"));
        uploadButton.Click();

        var confirmation = Browsers.getDriver.FindElement(By.XPath("//*[@id='uploaded-files']"));
        Assert.Contains("Manuscript_Unicode", confirmation.Text);
        Log.Info("File uploaded successfully.");
    }

    public static void CheckFileExists(string path)
    {
        Log.Info($"File path being checked: {path}");
        Log.Info($"File Exists: {File.Exists(path)}");
        
        if (!File.Exists(path))
        {
            Log.Info($"File does not exist at path: {path}");
            
            // Try to provide helpful debug info
            string directory = Path.GetDirectoryName(path);
            if (Directory.Exists(directory))
            {
                var files = Directory.GetFiles(directory);
                Log.Info($"Files in directory '{directory}':");
                foreach (var file in files)
                {
                    Log.Info($"  - {Path.GetFileName(file)}");
                }
            }
            else
            {
                Log.Info($"Directory does not exist: {directory}");
            }
        }
    }

    /// <summary>
    /// Sends a file path to a file input element, with special handling for Unicode characters in filenames.
    /// On Linux/headless environments, Selenium has issues with Unicode characters, so this method uses
    /// a workaround: it normalizes the Unicode string using NFC (Canonical Decomposition, followed by Canonical Composition).
    /// This ensures consistency with how the filesystem stores the file.
    /// </summary>
    public static bool SendFilePathToInputWithUnicodeSupport(string filePath)
    {
        try
        {
            // Validate file exists
            if (!File.Exists(filePath))
            {
                Log.Info($"File not found: {filePath}");
                CheckFileExists(filePath);
                return false;
            }

            Log.Info($"Sending file path to input: {filePath}");
            Log.Info($"File name: {Path.GetFileName(filePath)}");
            
            // Get absolute path
            string absolutePath = Path.GetFullPath(filePath);
            Log.Info($"Absolute path: {absolutePath}");

            // Normalize the path to NFC (Canonical Composition) form
            // This helps with Unicode character compatibility on different platforms
            string normalizedPath = absolutePath.Normalize(NormalizationForm.FormC);
            Log.Info($"Normalized path: {normalizedPath}");
            
            // Log the byte representation to diagnose encoding issues
            byte[] pathBytes = Encoding.UTF8.GetBytes(normalizedPath);
            Log.Info($"Path UTF8 bytes: {BitConverter.ToString(pathBytes)}");

            // Locate the file input element
            var fileInput = Browsers.getDriver.FindElement(By.XPath("//input[@type='file' and @id='file-upload']"));
            
            // Attempt to send the normalized path
            fileInput.SendKeys(normalizedPath);
            Log.Info($"Successfully sent file path: {filePath}");
            
            return true;
        }
        catch (OpenQA.Selenium.WebDriverArgumentException wdex) when (wdex.Message.Contains("File not found"))
        {
            // This is the specific error we're trying to diagnose
            Log.Info($"WebDriver 'File not found' error - this indicates a Selenium/ChromeDriver Unicode handling issue");
            Log.Info($"Error message: {wdex.Message}");
            
            // Try alternative approach: use xdotool on Linux if available
            if (IsLinux())
            {
                Log.Info("Running on Linux. Attempting alternative workaround using xdotool...");
                return SendFilePathUsingXdotool(filePath);
            }
            
            return false;
        }
        catch (Exception ex)
        {
            Log.Info($"Exception while sending filepath to upload input: {ex.Message}");
            Log.Info($"Exception type: {ex.GetType().Name}");
            Log.Info($"Exception details: {ex}");
            return false;
        }
    }

    /// <summary>
    /// Alternative workaround for Linux environments that have xdotool installed.
    /// xdotool can type the file path directly, bypassing Selenium's Unicode issues.
    /// </summary>
    private static bool SendFilePathUsingXdotool(string filePath)
    {
        try
        {
            Log.Debug("Attempting workaround using xdotool...");
            
            // First, make sure the input element is focused
            var fileInput = Browsers.getDriver.FindElement(By.XPath("//input[@type='file' and @id='file-upload']"));
            
            // Try clicking the element to focus it
            fileInput.Click();
            
            // Give it a moment to focus
            System.Threading.Thread.Sleep(500);
            
            string absolutePath = Path.GetFullPath(filePath);
            
            // Use xdotool to type the path
            var processInfo = new System.Diagnostics.ProcessStartInfo
            {
                FileName = "/usr/bin/xdotool",
                Arguments = $"type \"{absolutePath}\"",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true
            };

            using (var process = System.Diagnostics.Process.Start(processInfo))
            {
                process.WaitForExit(5000); // 5 second timeout
                
                if (process.ExitCode == 0)
                {
                    Log.Info("Successfully sent file path using xdotool");
                    return true;
                }
                else
                {
                    string error = process.StandardError.ReadToEnd();
                    Log.Info($"xdotool failed with exit code {process.ExitCode}: {error}");
                    return false;
                }
            }
        }
        catch (Exception ex)
        {
            Log.Info($"xdotool workaround failed: {ex.Message}");
            Log.Info($"This is expected if xdotool is not installed on the Linux system.");
            return false;
        }
    }

    /// <summary>
    /// Detects if the test is running on a Linux platform.
    /// </summary>
    private static bool IsLinux()
    {
        return System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(
            System.Runtime.InteropServices.OSPlatform.Linux);
    }
}

Debugging Logs

I have a test that needs to use a file with unicode character in the name called "Manuscript_Unicode_€.docx" and I need to use it to upload it to a page on the site to make sure the website supports the unicode character named files. Which works fine on windows, but on linux when I try to use the filepath to the file, it just doesn't work with the euro character in the name, it says the file file not found.
I expect the sendkeys to work with unicode characters also since the system is capable to use the characters, because it can add the character if I want to add the text to a normal input field.
Logs to see
2025-12-20 11:06:40,419 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: TestingUnicodeStuff0 - Line 82 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Constructed File Path: /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/bin/Debug/net8.0/TestData/SubmissionItems/SESMail/Manuscript_Unicode_€.docx  2025-12-20 11:06:40,419 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: TestingUnicodeStuff0 - Line 83 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] File Exists: True  2025-12-20 11:06:40,420 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 176 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Sending file path to input: /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/bin/Debug/net8.0/TestData/SubmissionItems/SESMail/Manuscript_Unicode_€.docx  2025-12-20 11:06:40,420 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 177 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] File name: Manuscript_Unicode_€.docx  2025-12-20 11:06:40,420 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 181 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Absolute path: /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/bin/Debug/net8.0/TestData/SubmissionItems/SESMail/Manuscript_Unicode_€.docx  2025-12-20 11:06:40,420 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 186 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Normalized path: /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/bin/Debug/net8.0/TestData/SubmissionItems/SESMail/Manuscript_Unicode_€.docx  2025-12-20 11:06:40,420 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 190 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Path UTF8 bytes: 2F-67-69-74-68-75-62-72-75-6E-6E-65-72-2F-5F-77-6F-72-6B-2F-65-64-69-74-6F-72-69-61-6C-6D-61-6E-61-67-65-72-2D-74-65-73-74-2D-61-75-74-6F-6D-61-74-69-6F-6E-2F-65-64-69-74-6F-72-69-61-6C-6D-61-6E-61-67-65-72-2D-74-65-73-74-2D-61-75-74-6F-6D-61-74-69-6F-6E-2F-46-65-61-74-75-72-65-54-65-73-74-73-2F-62-69-6E-2F-44-65-62-75-67-2F-6E-65-74-38-2E-30-2F-54-65-73-74-44-61-74-61-2F-53-75-62-6D-69-73-73-69-6F-6E-49-74-65-6D-73-2F-53-45-53-4D-61-69-6C-2F-4D-61-6E-75-73-63-72-69-70-74-5F-55-6E-69-63-6F-64-65-5F-E2-82-AC-2E-64-6F-63-78  2025-12-20 11:06:40,455 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 204 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] WebDriver 'File not found' error - this indicates a Selenium/ChromeDriver Unicode handling issue  2025-12-20 11:06:40,456 INFO EditorialManagerTestLibrary.Automation.Logger - [METHOD: SendFilePathToInputWithUnicodeSupport - Line 205 in /githubrunner/_work/editorialmanager-test-automation/editorialmanager-test-automation/FeatureTests/Search/DownloadPeopleSearchResults.cs] Error message: invalid argument: File not found
Note: I've been trying different workarounds but it feels like this should work out of the box.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions