Skip to content

Conversation

@Grantim
Copy link
Contributor

@Grantim Grantim commented Jan 11, 2026

Change in GLFW.onDrop when filesystem is enabled to support dropping directories

Change in GLFW.onDrop,  when filesystem is enabled to support dropping directories
@Grantim
Copy link
Contributor Author

Grantim commented Jan 11, 2026

Hello!

Please help me add new test for folder drop, I could only found https://github.com/emscripten-core/emscripten/blob/main/test/interactive/test_glfw_dropfile.c (which should work fine) but could not find how to run it locally

Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we don't have automatic testing of this.

Is there perhaps a test in test_interactive.py that we could add? Or at least can you confirm you have tested this locally?

}
else {
// fallback for browsers that does not support `webkitGetAsEntry`
for (var i = 0; i < event.dataTransfer.files.length; ++i) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for .. of here?

@Grantim
Copy link
Contributor Author

Grantim commented Jan 11, 2026

Thanks for comments, I have mostly updated code accordingly.


I guess we don't have automatic testing of this.

Is there perhaps a test in test_interactive.py that we could add? Or at least can you confirm you have tested this locally?

I will try to add something similar to test_glfw_dropfile.c to test dropping folders, as for local testing, I have only tested it on single configuration (window/chrome/wasm32)

@sbc100
Copy link
Collaborator

sbc100 commented Jan 11, 2026

Looks like closure compiler is complaining about: [JSC_UNDEFINED_VARIABLE] variable count is undeclared

Use shorter version for `DataTransferItem.prototype.webkitAsEntry` check 
Fix typo using `count` instead of `filenamesArray.length`
@Grantim
Copy link
Contributor Author

Grantim commented Jan 11, 2026

Looks like closure compiler is complaining about: [JSC_UNDEFINED_VARIABLE] variable count is undeclared

Oh, unfortunate typo. Fixed, thanks!

@sbc100
Copy link
Collaborator

sbc100 commented Jan 11, 2026

Hello!

Please help me add new test for folder drop, I could only found https://github.com/emscripten-core/emscripten/blob/main/test/interactive/test_glfw_dropfile.c (which should work fine) but could not find how to run it locally

To run that test locally you would do something like ./test/runner interactive.test_glfw_dropfile

if (fpIndex > -1) entriesTree[parentpath].subpaths.splice(fpIndex, 1);
if (recursive) markDone(parentpath, true);
if (Object.keys(entriesTree).length == 0) finalize();
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove semicolon here and below.

@Grantim
Copy link
Contributor Author

Grantim commented Jan 11, 2026

To run that test locally you would do something like ./test/runner interactive.test_glfw_dropfile

Thanks!
Trying to run it locally leads to [Browser harness server on thread Thread-2] (like any other interactive test case). Is it a known issue (if so, could you please help me with it)?

EDIT: full error:

Stderr:
[Browser harness server on thread Thread-2]
common:INFO: Using default CI configuration.


======================================================================
ERROR: setUpClass (test_interactive.interactive)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\WORK\git\emscripten\test\test_interactive.py", line 23, in setUpClass
    super().setUpClass()
  File "C:\WORK\git\emscripten\test\browser_common.py", line 755, in setUpClass
    cls.browser_open(cls.HARNESS_URL)
  File "C:\WORK\git\emscripten\test\browser_common.py", line 680, in browser_open
    os.mkdir(browser_data_dir)
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'C:\\WORK\\git\\emscripten\\out\\browser-profile'

@sbc100
Copy link
Collaborator

sbc100 commented Jan 11, 2026

To run that test locally you would do something like ./test/runner interactive.test_glfw_dropfile

Thanks! Trying to run it locally leads to [Browser harness server on thread Thread-2] (like any other interactive test case). Is it a known issue (if so, could you please help me with it)?

EDIT: full error:

Stderr:
[Browser harness server on thread Thread-2]
common:INFO: Using default CI configuration.


======================================================================
ERROR: setUpClass (test_interactive.interactive)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\WORK\git\emscripten\test\test_interactive.py", line 23, in setUpClass
    super().setUpClass()
  File "C:\WORK\git\emscripten\test\browser_common.py", line 755, in setUpClass
    cls.browser_open(cls.HARNESS_URL)
  File "C:\WORK\git\emscripten\test\browser_common.py", line 680, in browser_open
    os.mkdir(browser_data_dir)
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'C:\\WORK\\git\\emscripten\\out\\browser-profile'

Does mkdir out fix the issue?

@Grantim
Copy link
Contributor Author

Grantim commented Jan 11, 2026

It moved forward with new error, thanks again:

======================================================================
ERROR: setUpClass (test_interactive.interactive)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\WORK\git\emscripten\test\test_interactive.py", line 23, in setUpClass
    super().setUpClass()
  File "C:\WORK\git\emscripten\test\browser_common.py", line 755, in setUpClass
    cls.browser_open(cls.HARNESS_URL)
  File "C:\WORK\git\emscripten\test\browser_common.py", line 697, in browser_open
    cls.browser_procs = [subprocess.Popen(browser_args + config.open_url_args(url))]
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\grant\AppData\Local\Programs\Python\Python311\Lib\subprocess.py", line 1026, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Users\grant\AppData\Local\Programs\Python\Python311\Lib\subprocess.py", line 1538, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [WinError 2] The system cannot find the file specified

Stderr:
[Browser harness server on thread Thread-2]
common:INFO: Using default CI configuration.
common:INFO: Launching browser: ['google-chrome', '--no-first-run', '-start-maximized', '--no-sandbox', '--enable-unsafe-swiftshader', '--use-gl=swiftshader', '--enable-experimental-web-platform-features', '--enable-features=JavaScriptSourcePhaseImports', '--enable-experimental-webassembly-features', '--js-flags=--experimental-wasm-type-reflection --experimental-wasm-rab-integration', '--use-fake-device-for-media-stream', '--autoplay-policy=no-user-gesture-required', '--disk-cache-size=1', '--media-cache-size=1', '--disable-application-cache', '--disable-background-networking', '--password-store=basic', '--enable-logging=stderr', '--user-data-dir=C:\\WORK\\git\\emscripten\\out\\browser-profile']

----------------------------------------------------------------------

@sbc100
Copy link
Collaborator

sbc100 commented Jan 11, 2026

if you don't have google-chrome (the default browser) installed you can pass --browser=mybrowser to the test runner.

@sbc100
Copy link
Collaborator

sbc100 commented Jan 11, 2026

I'm curious how the out directory did not exist on your system since its used to store a the .stamp files from the boostrap process (which is required).

sbc100 added a commit to sbc100/emscripten that referenced this pull request Jan 11, 2026
@Grantim
Copy link
Contributor Author

Grantim commented Jan 11, 2026

I'm curious how the out directory did not exist on your system since its used to store a the .stamp files from the boostrap process (which is required).

To run this I cloned clean emscripten and emsdk and followed: https://emscripten.org/docs/contributing/developers_guide.html
Specifically (in emsdk):

emsdk install tot
emsdk activate tot

And then

cd C:\WORK\git\emscripten
set EM_CONFIG=C:\WORK\git\emsdk\.emscripten
test\runner interactive.test_glfw_dropfile

The local test I have mentioned before was done within this PR in our APP


if you don't have google-chrome (the default browser) installed you can pass --browser=mybrowser to the test runner.

Running like this reveals that I miss bootstrap and npm:

test\runner interactive.test_glfw_dropfile --browser="C:\Program Files\Google\Chrome\Application\chrome.exe"

Thanks!

@Grantim
Copy link
Contributor Author

Grantim commented Jan 11, 2026

Now after installing npm and doing bootstrap I am getting new error (which does not seem to be related to the PR, and reproduces on other interactive test cases too):

Browser stacks like this
image

test\runner interactive.test_glfw_dropfile --browser="C:\Program Files\Google\Chrome\Application\chrome.exe"

Running test_interactive: (1 tests)
[1/1] test_glfw_dropfile (test_interactive.interactive.test_glfw_dropfile) ... [10728:24048:0111/220525.350:INFO:components\enterprise\browser\controller\chrome_browser_cloud_management_controller.cc:206] No machine level policy manager exists.
[10728:8156:0111/220525.432:WARNING:chrome\browser\extensions\external_pref_loader.cc:296] You are using an old-style extension deployment method (external_extensions.json), which will soon be deprecated. (see http://developer.chrome.com/docs/extensions/how-to/distribute/install-extensions)
[10728:24048:0111/220525.878:ERROR:mojo\public\cpp\bindings\lib\interface_endpoint_client.cc:732] Message 0 rejected by interface blink.mojom.WidgetHost
[10728:24048:0111/220527.474:ERROR:components\device_event_log\device_event_log_impl.cc:198] [22:05:27.475] USB: usb_service_win.cc:105 SetupDiGetDeviceProperty({{A45C254E-DF1C-4EFD-8020-67D146A850E0}, 6}) failed: Element not found. (0x490)
[10728:25912:0111/220527.771:ERROR:google_apis\gcm\engine\registration_request.cc:292] Registration response error message: DEPRECATED_ENDPOINT
Created TensorFlow Lite XNNPACK delegate for CPU.
[10728:25912:0111/220548.882:ERROR:google_apis\gcm\engine\registration_request.cc:292] Registration response error message: DEPRECATED_ENDPOINT
[28036:6936:0111/220627.238:INFO:components\enterprise\browser\controller\chrome_browser_cloud_management_controller.cc:206] No machine level policy manager exists.
FAIL

Stdout:
[unresponsive test: test_interactive.interactive.test_glfw_dropfile total unresponsive=1]

Stderr:
common:INFO: Restarting browser process
common:INFO: Using default CI configuration.
common:INFO: Launching browser: ['C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', '--no-first-run', '-start-maximized', '--no-sandbox', '--enable-unsafe-swiftshader', '--use-gl=swiftshader', '--enable-experimental-web-platform-features', '--enable-features=JavaScriptSourcePhaseImports', '--enable-experimental-webassembly-features', '--js-flags=--experimental-wasm-type-reflection --experimental-wasm-rab-integration', '--use-fake-device-for-media-stream', '--autoplay-policy=no-user-gesture-required', '--disk-cache-size=1', '--media-cache-size=1', '--disable-application-cache', '--disable-background-networking', '--password-store=basic', '--enable-logging=stderr', '--user-data-dir=C:\\WORK\\git\\emscripten\\out\\browser-profile']


======================================================================
FAIL: test_glfw_dropfile (test_interactive.interactive.test_glfw_dropfile)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\WORK\git\emscripten\test\test_interactive.py", line 221, in test_glfw_dropfile
    self.btest_exit('interactive/test_glfw_dropfile.c', cflags=['-sUSE_GLFW=3', '-lglfw', '-lGL'])
  File "C:\WORK\git\emscripten\test\browser_common.py", line 904, in btest_exit
    return self.btest(filename, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\WORK\git\emscripten\test\browser_common.py", line 945, in btest
    self.run_browser(html_file, expected=['/report_result?' + e for e in expected], timeout=timeout)
  File "C:\WORK\git\emscripten\test\browser_common.py", line 857, in run_browser
    raise e
  File "C:\WORK\git\emscripten\test\browser_common.py", line 848, in run_browser
    self.assertContained(expected, output)
  File "C:\WORK\git\emscripten\test\common.py", line 1072, in assertContained
    self.fail("Expected to find '%s' in '%s', diff:\n\n%s\n%s" % (
AssertionError: Expected to find '/report_result?exit:0
' in '[no http server activity]
', diff:

--- expected
+++ actual
@@ -1 +1 @@
-/report_result?exit:0
+[no http server activity]



Stdout:
[unresponsive test: test_interactive.interactive.test_glfw_dropfile total unresponsive=1]

Stderr:
common:INFO: Restarting browser process
common:INFO: Using default CI configuration.
common:INFO: Launching browser: ['C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', '--no-first-run', '-start-maximized', '--no-sandbox', '--enable-unsafe-swiftshader', '--use-gl=swiftshader', '--enable-experimental-web-platform-features', '--enable-features=JavaScriptSourcePhaseImports', '--enable-experimental-webassembly-features', '--js-flags=--experimental-wasm-type-reflection --experimental-wasm-rab-integration', '--use-fake-device-for-media-stream', '--autoplay-policy=no-user-gesture-required', '--disk-cache-size=1', '--media-cache-size=1', '--disable-application-cache', '--disable-background-networking', '--password-store=basic', '--enable-logging=stderr', '--user-data-dir=C:\\WORK\\git\\emscripten\\out\\browser-profile']

----------------------------------------------------------------------
Ran 1 test in 62.842s

@sbc100
Copy link
Collaborator

sbc100 commented Jan 11, 2026

I'm curious how the out directory did not exist on your system since its used to store a the .stamp files from the boostrap process (which is required).

To run this I cloned clean emscripten and emsdk and followed: https://emscripten.org/docs/contributing/developers_guide.html Specifically (in emsdk):

emsdk install tot
emsdk activate tot

And then

cd C:\WORK\git\emscripten
set EM_CONFIG=C:\WORK\git\emsdk\.emscripten
test\runner interactive.test_glfw_dropfile

The looks like the correct way to go about it.

However, emcc should complain if the .stamp files generated by bootstrap are missing.

I've uploaded this PR to make it more obvious: #26086

sbc100 added a commit to sbc100/emscripten that referenced this pull request Jan 11, 2026
sbc100 added a commit to sbc100/emscripten that referenced this pull request Jan 11, 2026
@sbc100
Copy link
Collaborator

sbc100 commented Jan 11, 2026

The idea with interactive tests is that you interact with the web page to confirm stuff is working.

They don't get run very often so they tend to bitrot. Are you able to confirm the behaviour of the program while the test is running (before it gets reported as unresponsive).

@Grantim
Copy link
Contributor Author

Grantim commented Jan 12, 2026

Seems that rebooting my PC fixed issues with the test somehow.
I have updated it to validate directories drop, and tested locally (with both file, and directory tree)
Also removed excessive semicolons

void on_file_drop(GLFWwindow *window, int count, const char **paths) {
for (int i = 0; i < count; ++i) {
printf("dropped file %s\n", paths[i]);
int flags = FTW_PHYS; // Do not follow symbolic links
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just inline FTW_PHYS in the call to nftw

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

*/

#include <stdio.h>
#include <ftw.h>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, I've been using UNIX for over 30 years and I've never come across this API before! TIL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually it was suggest to me by google AI while searching how to traverse directory using C lang

@sbc100 sbc100 enabled auto-merge (squash) January 12, 2026 16:32
sbc100 added a commit to sbc100/emscripten that referenced this pull request Jan 12, 2026
@sbc100 sbc100 merged commit d5093b7 into emscripten-core:main Jan 12, 2026
35 checks passed
@Grantim Grantim deleted the patch-1 branch January 12, 2026 17:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants