Repository: deno
Issue: Support Custom Signal Listeners or a Global `afterAll` Hook in `deno test`
Labels: testing

## Description

It appears that when defining tests with `Deno.test()` and running them using `deno test`, adding custom signal listeners (e.g. `Deno.addSignalListener`) does not work as expected. The `deno test` runner seems to ignore these listeners, as the signals are only handled internally within the test runner's Rust implementation.

In my use case, I am building a test wrapper that awaits a global asynchronous teardown function during a final test step. While this works well during normal test execution, I want the teardown function to be triggered even when the test suite exits unexpectedly, such as when a `SIGINT` or `SIGTERM` signal is received.

Here is a simplified example:

```ts
Deno.addSignalListener("SIGINT", () => {
  console.log("Initiating cleanup before exiting...");
  // Perform teardown actions, then exit
});

// Calls Deno.test() internally and registers teardown logic within a test-step
await runTestSuiteAndRegisterTests();
```

However, when running the test suite with `deno test`, the signal listener is never triggered. Instead, the `deno test` runner uses its own signal handler and outputs the following when interrupted:

```
SIGINT The following tests were pending:

run mytopleveltest => ./packages/mypackage/src/runner.ts:42:42
```

This behavior prevents custom signal listeners from being used to handle cleanup tasks or shutdown hooks effectively.

## Feature Request

To make `deno test` more flexible and customizable for advanced test scenarios, I propose one of the following enhancements:

1. **Support for Custom Signal Listeners**:
   - Allow users to register their own signal listeners (`Deno.addSignalListener`) in addition to the test runner's default handlers.
   - This would enable users to handle signals like `SIGINT` or `SIGTERM` and execute custom logic, such as cleanup functions, before the process exits.

2. **A Global `afterAll` Hook**:
   - Introduce a global `afterAll` hook that is executed after all tests complete, regardless of how the test suite terminates (e.g., normal exit or signal interruption).
   - The `afterAll` hook would allow users to register teardown logic that ensures proper cleanup before the process exits.
   - the hook should allow passing in synchronous functions as well as asynchronous functions that will be awaited

## Expected Behavior

- If a `Deno.addSignalListener` is registered, the test runner should invoke the user's listener(s) in addition to its own internal signal handling.
- Alternatively, a global `afterAll` hook would provide a standardized way to execute cleanup logic at the end of the test suite, regardless of how the suite terminates.

## Use Case

This feature would enable advanced test suite behaviors, such as:
- Cleaning up global resources (e.g. databases, external services, or temporary files) when the suite exits.
- Ensuring all test lifecycle hooks (setup, execution, teardown) are handled gracefully, even in interrupted scenarios.

## Current Behavior

Currently, `deno test`:
- Ignores user-defined signal listeners and only uses its internal Rust signal handling.
- Outputs pending tests on signal interruption but does not allow for custom cleanup logic to run.

## Conclusion

Adding support for custom signal listeners or a global `afterAll` hook would greatly enhance the flexibility and usability of the `deno test` runner, especially for users with complex test suite requirements.

Thank you for considering this feature request! I'm happy to provide further details or examples if needed.