Initial public release of Warp.
Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
# Integration tests in Warp
|
||||
This is a short guide into writing integration tests in Warp.
|
||||
|
||||
## When to add a new integration test?
|
||||
Our general philosophy around how we see unit vs integration testing can be summarized as follows:
|
||||
### Write unit tests when:
|
||||
* Testing a single function;
|
||||
* Function has minimal deps and no pty deps;
|
||||
* Can run purely in rust, e.g. a parser.
|
||||
|
||||
### Integration testing can help:
|
||||
* Test some use-case from the user perspective;
|
||||
* In scenarios that are slower or require a shell.
|
||||
|
||||
## What makes a good integration test?
|
||||
Test typically has the format:
|
||||
* Setup some state in the app;
|
||||
* Simulate a user action (e.g. type or click);
|
||||
* Verify that the app is in the expected state.
|
||||
|
||||
## How to add a new integration test?
|
||||
Our integration tests currently require you to work with **3** files: [integration/tests/integration.rs](integration.rs), [integration/src/bin/integration.rs](../src/bin/integration.rs), and [integration/src/test.rs](../src/test.rs). (Most tests live in `test.rs` today, but you might want to write yours in a separate file.)
|
||||
|
||||
Let's start with writing a *new integration test* for your feature. To do that, simply add a new method to [integration/src/bin/integration.rs](../src/bin/integration.rs). It should take **0 arguments** and **return `TestDriver`** object. You should also register it in `register_tests()` method in the same file, and later on (to ensure it's being executed) adding it to [integration/tests/integration.rs](integration.rs) in the `integration_tests!` macro. As a convention, each test method name starts with `test_` prefix (note, however, that it doesn't require the `#[test]` annotation like usual unit tests in Rust).
|
||||
|
||||
Now that you've made the first step, it's time to make use of the integration test framework. Let's use the following example to talk more about what's possible to do in integration tests (you'll find more explanation in the comments):
|
||||
|
||||
```rs
|
||||
fn test_simple_example() -> TestDriver {
|
||||
new_builder() // initializes the integration test builder
|
||||
// each test can have multiple steps, which are more or less complicated,
|
||||
// for example - you can wait for a specific action to happen, like in the line below!
|
||||
.with_step(wait_for_bootstrapping(0))
|
||||
.with_step(
|
||||
// You can also create your own `TestStep`!
|
||||
TestStep::new("Run ls and verify block exists") // Each `TestStep` has a name
|
||||
// ...and later lets you specify what happens. You can verify which characters were typed:
|
||||
.with_keystrokes(&[
|
||||
Keystroke::parse("l").unwrap(),
|
||||
Keystroke::parse("s").unwrap(),
|
||||
Keystroke::parse("enter").unwrap(),
|
||||
])
|
||||
// ...set timeouts after which the test is doomed:
|
||||
.set_timeout(Duration::from_secs(5))
|
||||
// ...specify certain assertions:
|
||||
.set_assertion(Box::new(|app, window_id, presenter| {
|
||||
let presenter = presenter.expect("presenter should be set");
|
||||
assert!(presenter.scene().is_some());
|
||||
let views = app.views_of_type(window_id).unwrap();
|
||||
let terminal_view: &ViewHandle<TerminalView> = views.get(0).unwrap();
|
||||
terminal_view.read(app, |view, _ctx| {
|
||||
let model = view.model.lock();
|
||||
async_assert!(
|
||||
!model.is_block_list_empty(),
|
||||
"Block list should not be empty"
|
||||
)
|
||||
})
|
||||
})),
|
||||
)
|
||||
.build()
|
||||
}
|
||||
```
|
||||
|
||||
I find `with_keystrokes` and `with_input_string` most helpful methods, so far. You can check the implementation (and expand it!) in [ui/src/integration/test_driver.rs](../../ui/src/integration/test_driver.ts).
|
||||
|
||||
## When to use `assert!` vs `async_assert!`
|
||||
The former will fail the test the first time it's false. The latter will fail the test if we don't ever see a success in the timeout. If you don't specify a timeout, the default timeout is used.
|
||||
|
||||
In our UI framework, dispatching events and actions are generally synchronous. Concurrency comes mainly from the event loop.
|
||||
|
||||
Example of synchronous assertion:
|
||||
This panicks if it fails the first time. Otherwise, it succeeds.
|
||||
```rs
|
||||
assert_eq!(
|
||||
view.buffer_text(ctx),
|
||||
"".to_string(),
|
||||
"Input should be empty"
|
||||
);
|
||||
AssertionOutcome::Success
|
||||
```
|
||||
|
||||
Example of async assertion:
|
||||
```rs
|
||||
async_assert_eq!(
|
||||
expect_bootstrapped,
|
||||
bootstrapped,
|
||||
"terminal should be bootstrapped ({})",
|
||||
expect_bootstrapped
|
||||
)
|
||||
```
|
||||
|
||||
Since many of our tests are async, I would recommend running in a loop locally before merging to avoid flakes e.g.
|
||||
```sh
|
||||
for i in {0..100}; do
|
||||
WARPUI_USE_REAL_DISPLAY_IN_INTEGRATION_TESTS=1 RUST_BACKTRACE=full WARP_SHELL_PATH=/bin/bash cargo run -p integration -- test_simple_example
|
||||
if [ $? -ne 0 ]; then return; fi
|
||||
done
|
||||
```
|
||||
|
||||
This has helped us catch a lot of existing bugs in the system.
|
||||
|
||||
Note that for `async_assert` to actually work, the `set_assertion` needs to **return** with the `async_assert`.
|
||||
|
||||
## How to add a sqlite snapshot?
|
||||
* You can copy over a warp.sqlite file from ~/Library/Application\ Support/{warp, dev.warp.Warp-(Dev|Preview|Stable)} directly
|
||||
* You may want to sanitize some info that is specific to you (i.e. cwd https://staging.warp.dev/block/FNBafyVtxvjmdNIx6HxUM5)
|
||||
|
||||
|
||||
### How to run integration tests?
|
||||
To run a specific integration test you can use:
|
||||
```
|
||||
WARPUI_USE_REAL_DISPLAY_IN_INTEGRATION_TESTS="1" cargo run --bin integration -- test_simple_example
|
||||
```
|
||||
|
||||
The `WARPUI_USE_REAL_DISPLAY_IN_INTEGRATION_TESTS="1"` will force the new terminal window to open, which helps a lot when iterating on your integration test implementation!
|
||||
|
||||
### Known issues / limitations
|
||||
* To determine (from the `TestStep`) which shell is used for the test, you can try checking `WARP_SHELL_PATH` environment variable (that works within the CI on github) or check the passwd for the user (for local runs).
|
||||
* Similarly you can run the test with a specific shell by setting the `WARP_SHELL_PATH` and then running the test. Note that if you're running with fish, you also need to pass in `--features fish_shell` until that feature flag is removed. For example: `WARP_SHELL_PATH=/usr/local/bin/fish`, then `cargo run --bin integration --features fish_shell -- test_simple_example`
|
||||
* Bindings aren't exposed by default in integration tests, add them in the file of the original binding. Example from `editor/view.rs`:
|
||||
|
||||
```rust
|
||||
if ChannelState::channel() == Channel::Integration {
|
||||
app.register_fixed_bindings([
|
||||
// Hack: Add explicit bindings for the tests, since the tests' injected
|
||||
// keypresses won't trigger Mac menu items. Unfortunately we can't use
|
||||
// cfg[test] because we are a separate process!
|
||||
Binding::new(
|
||||
"cmd-z",
|
||||
EditorAction::Undo,
|
||||
Some("EditorView && !IMEOpen")
|
||||
),
|
||||
]);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,122 @@
|
||||
use command::blocking::Command;
|
||||
use std::env;
|
||||
use std::process::Stdio;
|
||||
use warpui::integration::RERUN_EXIT_CODE;
|
||||
|
||||
const MAX_TEST_RUNS: usize = 10;
|
||||
|
||||
/// Runs a single integration test.
|
||||
///
|
||||
/// This runs the `integration` binary from the `warp` crate, passing it the
|
||||
/// name of the test to execute as the one positional argument.
|
||||
pub fn run_integration_test(name: &str) -> Result<(), String> {
|
||||
let mut keep_going = true;
|
||||
let mut run_num = 0;
|
||||
while keep_going {
|
||||
let inherited_envs = env::vars_os().filter(|(k, _v)| {
|
||||
let k = k
|
||||
.to_str()
|
||||
.expect("environment variable keys should contain valid unicode");
|
||||
// Propagate the PATH to the integration test
|
||||
// process, otherwise the shell it spawns might not
|
||||
// be able to find the binaries it needs to execute.
|
||||
k == "PATH"
|
||||
// Propagate any Rust-related variables.
|
||||
|| k.starts_with("RUST_")
|
||||
// Propagate any Warp-specific variables.
|
||||
|| k.starts_with("WARP_")
|
||||
|| k.starts_with("WARPUI_")
|
||||
// Propagate any wgpu-specific variables.
|
||||
|| k.starts_with("WGPU_")
|
||||
// Make sure the test knows what X or Wayland server to use.
|
||||
|| k == "DISPLAY"
|
||||
|| k == "WAYLAND_DISPLAY"
|
||||
// Propagate XDG_RUNTIME_DIR, which is needed for tests to run.
|
||||
// We actively _do not_ want to propagate other XDG_ variables,
|
||||
// as they tend to encode the home directory, which we override
|
||||
// in tests to point to a per-test temporary directory.
|
||||
|| k == "XDG_RUNTIME_DIR"
|
||||
// Propogate XAUTHORITY so we can run headless tests using xvfb.
|
||||
|| k == "XAUTHORITY"
|
||||
});
|
||||
keep_going = match Command::new(env!("CARGO_BIN_EXE_integration"))
|
||||
.arg(name)
|
||||
.env_clear()
|
||||
.envs(inherited_envs)
|
||||
.env("WARP_INTEGRATION", "1")
|
||||
.stdout(Stdio::inherit())
|
||||
.stderr(Stdio::inherit())
|
||||
.status()
|
||||
{
|
||||
Ok(status) => match status.code() {
|
||||
Some(0) => {
|
||||
println!("Test exited with success.");
|
||||
false
|
||||
}
|
||||
Some(RERUN_EXIT_CODE) if run_num < MAX_TEST_RUNS => {
|
||||
println!("Test exited with rerun code, trying again.");
|
||||
run_num += 1;
|
||||
true
|
||||
}
|
||||
Some(exit_code) => {
|
||||
return std::result::Result::Err(format!(
|
||||
"Test {name} failed with exit code {exit_code}",
|
||||
));
|
||||
}
|
||||
None => {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::process::ExitStatusExt;
|
||||
let signal = status
|
||||
.signal()
|
||||
.and_then(|signal| nix::sys::signal::Signal::try_from(signal).ok());
|
||||
if let Some(signal) = signal {
|
||||
return std::result::Result::Err(format!(
|
||||
"Test {name} failed due to signal {}",
|
||||
signal.as_str(),
|
||||
));
|
||||
} else {
|
||||
return std::result::Result::Err(format!(
|
||||
"Test {name} failed for unknown reason",
|
||||
));
|
||||
}
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
return std::result::Result::Err(format!(
|
||||
"Test {name} failed for unknown reason",
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
return std::result::Result::Err(format!("Test {name} failed with error {err:#}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! integration_tests {
|
||||
( $(
|
||||
$(#[$args:meta])*
|
||||
$name:ident,
|
||||
)*
|
||||
) => {
|
||||
$(
|
||||
$(#[$args])*
|
||||
// Ignore unused attributes, in case we're marking a test as
|
||||
// ignored twice, once via arguments passed to the macro and once
|
||||
// below.
|
||||
#[allow(unused_attributes)]
|
||||
// For right now, we only want to run integration tests on macOS
|
||||
// and Linux (iff the run_on_linux feature is enabled).
|
||||
#[cfg_attr(not(any(target_os = "macos", feature = "run_on_linux")), ignore)]
|
||||
#[test]
|
||||
fn $name() -> Result<(), String> {
|
||||
$crate::common::run_integration_test(stringify!($name))
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This file echoes a bunch of 24-bit color codes
|
||||
# to the terminal to demonstrate its functionality.
|
||||
# The foreground escape sequence is ^[38;2;<r>;<g>;<b>m
|
||||
# The background escape sequence is ^[48;2;<r>;<g>;<b>m
|
||||
# <r> <g> <b> range from 0 to 255 inclusive.
|
||||
# The escape sequence ^[0m returns output to default
|
||||
|
||||
setBackgroundColor()
|
||||
{
|
||||
echo -en "\x1b[48;2;$1;$2;$3""m"
|
||||
}
|
||||
|
||||
resetOutput()
|
||||
{
|
||||
echo -en "\x1b[0m\n"
|
||||
}
|
||||
|
||||
# Gives a color $1/255 % along HSV
|
||||
# Who knows what happens when $1 is outside 0-255
|
||||
# Echoes "$red $green $blue" where
|
||||
# $red $green and $blue are integers
|
||||
# ranging between 0 and 255 inclusive
|
||||
rainbowColor()
|
||||
{
|
||||
let h=$1/43
|
||||
let f=$1-43*$h
|
||||
let t=$f*255/43
|
||||
let q=255-t
|
||||
|
||||
if [ $h -eq 0 ]
|
||||
then
|
||||
echo "255 $t 0"
|
||||
elif [ $h -eq 1 ]
|
||||
then
|
||||
echo "$q 255 0"
|
||||
elif [ $h -eq 2 ]
|
||||
then
|
||||
echo "0 255 $t"
|
||||
elif [ $h -eq 3 ]
|
||||
then
|
||||
echo "0 $q 255"
|
||||
elif [ $h -eq 4 ]
|
||||
then
|
||||
echo "$t 0 255"
|
||||
elif [ $h -eq 5 ]
|
||||
then
|
||||
echo "255 0 $q"
|
||||
else
|
||||
# execution should never reach here
|
||||
echo "0 0 0"
|
||||
fi
|
||||
}
|
||||
|
||||
for j in `seq 0 100`; do
|
||||
|
||||
for i in `seq 0 127`; do
|
||||
setBackgroundColor $i 0 0
|
||||
echo -en " "
|
||||
done
|
||||
resetOutput
|
||||
for i in `seq 255 128`; do
|
||||
setBackgroundColor $i 0 0
|
||||
echo -en " "
|
||||
done
|
||||
resetOutput
|
||||
|
||||
for i in `seq 0 127`; do
|
||||
setBackgroundColor 0 $i 0
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
for i in `seq 255 128`; do
|
||||
setBackgroundColor 0 $i 0
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
|
||||
for i in `seq 0 127`; do
|
||||
setBackgroundColor 0 0 $i
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
for i in `seq 255 128`; do
|
||||
setBackgroundColor 0 0 $i
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
|
||||
for i in `seq 0 127`; do
|
||||
setBackgroundColor `rainbowColor $i`
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
for i in `seq 255 128`; do
|
||||
setBackgroundColor `rainbowColor $i`
|
||||
echo -n " "
|
||||
done
|
||||
resetOutput
|
||||
done
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
chars=`echo $((64*1024*1024))`
|
||||
openssl rand -hex $chars
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
# Integration Test
|
||||
|
||||
This is a Markdown file read by the `test_restore_snapshot_with_markdown_file` integration test.
|
||||
@@ -0,0 +1,2 @@
|
||||
// This is a test file
|
||||
struct Something {}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
# Warp Launch Configuration
|
||||
#
|
||||
#
|
||||
# Use this to start a certain configuration of windows, tabs, and panes
|
||||
# Open the launch configuration palette to access and open any launch configuration
|
||||
#
|
||||
# This file defines your launch configuration
|
||||
# More on how to do so here: [link to docs]
|
||||
#
|
||||
# All launch configurations are stored under ~/.warp/launch_configurations/
|
||||
# Edit them anytime!
|
||||
|
||||
---
|
||||
name: Launch Config
|
||||
windows:
|
||||
- tabs:
|
||||
- layout:
|
||||
split_direction: horizontal
|
||||
panes:
|
||||
- cwd: /Users/zhengtao/src/warp-internal/app/src/terminal
|
||||
- cwd: /Users/zhengtao/src/warp-internal
|
||||
- layout:
|
||||
cwd: /Users/zhengtao/src/warp-internal
|
||||
- layout:
|
||||
cwd: /Users/zhengtao/src/warp-internal
|
||||
- tabs:
|
||||
- layout:
|
||||
split_direction: horizontal
|
||||
panes:
|
||||
- cwd: /Users/zhengtao
|
||||
- cwd: /Users/zhengtao
|
||||
- layout:
|
||||
cwd: /Users/zhengtao
|
||||
- layout:
|
||||
cwd: /Users/zhengtao
|
||||
- tabs:
|
||||
- layout:
|
||||
cwd: /Users/zhengtao
|
||||
Binary file not shown.
@@ -0,0 +1,24 @@
|
||||
|
||||
accent: '#01a0e4'
|
||||
background: '#090300'
|
||||
details: darker
|
||||
foreground: '#a5a2a2'
|
||||
terminal_colors:
|
||||
bright:
|
||||
black: '#5c5855'
|
||||
blue: '#807d7c'
|
||||
cyan: '#cdab53'
|
||||
green: '#3a3432'
|
||||
magenta: '#d6d5d4'
|
||||
red: '#e8bbd0'
|
||||
white: '#f7f7f7'
|
||||
yellow: '#4a4543'
|
||||
normal:
|
||||
black: '#090300'
|
||||
blue: '#01a0e4'
|
||||
cyan: '#b5e4f4'
|
||||
green: '#01a252'
|
||||
magenta: '#a16a94'
|
||||
red: '#db2d20'
|
||||
white: '#a5a2a2'
|
||||
yellow: '#fded02'
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
accent: '#01a0e4'
|
||||
background: '#090300'
|
||||
details: darker
|
||||
foreground: '#a5a2a2'
|
||||
terminal_colors:
|
||||
bright:
|
||||
black: '#5c5855'
|
||||
blue: '#807d7c'
|
||||
cyan: '#cdab53'
|
||||
green: '#3a3432'
|
||||
magenta: '#d6d5d4'
|
||||
red: '#e8bbd0'
|
||||
white: '#f7f7f7'
|
||||
yellow: '#4a4543'
|
||||
normal:
|
||||
black: '#090300'
|
||||
blue: '#01a0e4'
|
||||
cyan: '#b5e4f4'
|
||||
green: '#01a252'
|
||||
magenta: '#a16a94'
|
||||
red: '#db2d20'
|
||||
white: '#a5a2a2'
|
||||
yellow: '#fded02'
|
||||
name: test_theme
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: "Run Warp locally with shell"
|
||||
command: "WARP_SHELL_PATH={{shell}} cargo run"
|
||||
description: "Runs warp with the particular shell so devs don't need to change their login shell to test a different shell locally"
|
||||
arguments:
|
||||
- name: shell
|
||||
description: path of shell to use
|
||||
author: Warp Team
|
||||
shells: []
|
||||
---
|
||||
name: "Run Warp locally with shell 2: Electric Boogaloo"
|
||||
command: "WARP_SHELL_PATH={{shell}} cargo run"
|
||||
description: "Runs warp with the particular shell so devs don't need to change their login shell to test a different shell locally"
|
||||
arguments:
|
||||
- name: shell
|
||||
description: path of shell to use
|
||||
author: Warp Team
|
||||
shells: []
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
mod common;
|
||||
#[path = "integration/shell_integration_tests.rs"]
|
||||
mod shell_integration_tests;
|
||||
#[path = "integration/ui_tests.rs"]
|
||||
mod ui_tests;
|
||||
@@ -0,0 +1,122 @@
|
||||
//! Tests that need to run against every supported shell.
|
||||
//!
|
||||
//! Add a test to this module if any of the following are true:
|
||||
//! * It needs to run against every shell.
|
||||
//! * It needs to run against a _specific_ shell or set of shells.
|
||||
//!
|
||||
//! When adding a test to this module, please add a brief comment indicating
|
||||
//! why it belongs here.
|
||||
|
||||
use super::integration_tests;
|
||||
|
||||
integration_tests! {
|
||||
// Test command execution works.
|
||||
test_single_command,
|
||||
// Test shell process terminates when session is closed.
|
||||
test_add_and_close_session,
|
||||
// Test powerlevel10k detection (via bootstrap script logic).
|
||||
test_detect_powerlevel10k,
|
||||
// Test properties of bootstrap.
|
||||
test_bootstrap_with_no_script_execution_block,
|
||||
test_rc_files_only_sourced_once_during_bootstrapping,
|
||||
// Test ctrl-c terminates long-running commands.
|
||||
test_ctrl_c,
|
||||
// Test copying a block's command gives us the expected command string.
|
||||
test_open_context_menu_and_execute_command,
|
||||
// Test we get the right metadata from a bootstrapped shell.
|
||||
test_block_metadata_received,
|
||||
// Test typeahead behavior.
|
||||
test_typeahead,
|
||||
// Test input reporting behavior.
|
||||
test_input_reporting_posix_shells,
|
||||
test_input_reporting_powershell,
|
||||
// Test background output behavior.
|
||||
test_background_output,
|
||||
// Must run against zsh.
|
||||
test_zshrc_keypress,
|
||||
// Tests bash- and zsh-specific behavior.
|
||||
test_alias_guards_on_ps1_set,
|
||||
// Tests prompt information from shell.
|
||||
test_ps1_value_not_null_or_exit,
|
||||
// Tests bash-specific behavior.
|
||||
test_custom_ps1_expansion_bash,
|
||||
// Tests zsh-specific behavior.
|
||||
test_auto_title,
|
||||
// Tests zsh-specific behavior.
|
||||
test_warp_auto_title_disabled,
|
||||
// Tests bash-specific behavior.
|
||||
test_warp_honors_user_title_bash,
|
||||
// Tests zsh-specific behavior.
|
||||
test_warp_honors_user_title_zsh,
|
||||
// Tests shell-specific "autocd" behavior.
|
||||
test_completions_with_autocd,
|
||||
// Tests bootstrap reports completable executables.
|
||||
test_executable_completions,
|
||||
// Tests bootstrap reports completable functions.
|
||||
test_function_completions,
|
||||
// Tests bootstrap reports completable builtins.
|
||||
test_builtin_completions,
|
||||
// Tests bootstrap reports completable keywords.
|
||||
test_keyword_completions,
|
||||
// Tests bash-specific behavior.
|
||||
test_histcontrol_env_var,
|
||||
// Tests initial working directory behavior.
|
||||
test_create_session_with_new_tab_while_bootstrapping,
|
||||
// Tests initial working directory behavior.
|
||||
test_start_shell_in_deleted_directory,
|
||||
// Tests prompt information (sent during precmd).
|
||||
test_git_prompt,
|
||||
// Tests shell initialization.
|
||||
test_terminal_announces_capabilities_to_shell,
|
||||
// Tests bash-specific behavior.
|
||||
test_bash_bootstraps_with_prompt_command_array,
|
||||
test_bash_bootstraps_with_prompt_command_array_that_sets_ps1,
|
||||
// Test runs only on zsh.
|
||||
test_color_overrides_in_prompt_dont_crash,
|
||||
// Tests zsh-specific behavior with nounset option.
|
||||
test_zsh_bootstraps_with_nounset_option,
|
||||
|
||||
// Tests of ssh wrapper logic from bootstrap script.
|
||||
test_legacy_ssh_into_bash,
|
||||
test_legacy_ssh_into_zsh,
|
||||
test_tmux_ssh_into_bash,
|
||||
test_tmux_ssh_into_zsh,
|
||||
// TODO(vorporeal): Reenable fish once we actually support it as a remote
|
||||
// shell.
|
||||
// test_ssh_into_fish,
|
||||
test_ssh_into_sh,
|
||||
test_ssh_into_ash,
|
||||
|
||||
// Tests of custom prompt behavior.
|
||||
test_copy_prompt_from_block_honor_ps1_enabled,
|
||||
test_copy_prompt_from_input_honor_ps1_enabled,
|
||||
|
||||
// Disabled due to flakiness on CI.
|
||||
#[ignore]
|
||||
test_copy_rprompt_from_input_honor_ps1_enabled,
|
||||
|
||||
// Tests of subshell logic from bootstrap script.
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_can_bootstrap_local_bash_subshell,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_can_bootstrap_local_zsh_subshell,
|
||||
// Disabled due to flakiness on CI.
|
||||
#[ignore]
|
||||
test_can_bootstrap_local_fish_subshell,
|
||||
|
||||
// Tests loading command history from shell histfile.
|
||||
test_command_search_loads_history,
|
||||
test_histfile_left_joined_with_persisted_history,
|
||||
|
||||
// Tests default prompt behavior.
|
||||
test_context_chips_prompt_at_bootstrap,
|
||||
|
||||
// CTRL-D tests.
|
||||
test_ctrl_d_eot,
|
||||
test_ctrl_d_exit,
|
||||
test_ctrl_d_handled_by_read_during_bootstrapping,
|
||||
test_ctrl_d_during_bootstrapping_exits_shell_upon_completion,
|
||||
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_git_prompt_chips,
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
//! Tests that cover application UI interactions and not external integrations.
|
||||
//!
|
||||
//! If any of the following are true, a test DOES NOT belong here:
|
||||
//! * It needs to run against every shell.
|
||||
//! * It needs to run against a _specific_ shell or set of shells.
|
||||
|
||||
use super::integration_tests;
|
||||
|
||||
integration_tests! {
|
||||
test_add_many_sessions,
|
||||
test_ctrl_tab_session_switching,
|
||||
test_hover_over_menu,
|
||||
test_shell_reinitializing,
|
||||
test_exit_multiple_tabs,
|
||||
test_execute_multiple_cursor_command,
|
||||
test_home_key_should_not_appear_in_input,
|
||||
test_change_font_size,
|
||||
test_long_running_block_height_updated,
|
||||
test_instant_prompt_bootstrap,
|
||||
test_unescaped_prompt_bootstraps,
|
||||
test_unnecessary_resizes,
|
||||
test_removing_tabs_out_of_order,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_suggestions_menu_positioning,
|
||||
test_open_and_close_theme_creator_modal,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_click_on_prompt_to_focus_input,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_text_input_on_block_list,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_text_input_on_block_list_while_composing,
|
||||
#[ignore]
|
||||
test_open_and_close_resource_center,
|
||||
test_open_and_close_context_menu_with_keybinding,
|
||||
test_open_and_close_settings,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_scroll_to_hidden_block_and_open_context_menu_with_keybinding,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_block_navigation,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_waterfall_input,
|
||||
#[ignore]
|
||||
test_waterfall_input_text_selection,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_waterfall_input_scrolling,
|
||||
#[ignore = "Flakes in CI"]
|
||||
test_waterfall_input_after_command_execution,
|
||||
test_waterfall_input_alt_grid,
|
||||
test_undo_redo,
|
||||
#[cfg(target_os="macos")]
|
||||
// TODO(alokedesai): Add support for cascading windows when opening new windows via winit.
|
||||
test_add_windows_correct_position_and_cascade,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_find_within_block,
|
||||
test_case_sensitive_find,
|
||||
test_find_bar_autoselects_text,
|
||||
test_disabling_action_dispatching,
|
||||
test_session_restoration,
|
||||
test_restored_blocks_on_different_hosts,
|
||||
test_restore_snapshot_with_deleted_cwd,
|
||||
test_session_restoration_with_multiple_shells,
|
||||
test_restore_snapshot_with_background_output,
|
||||
test_restore_snapshot_with_notebooks,
|
||||
test_restore_snapshot_with_workflows,
|
||||
test_restore_snapshot_with_test_json_object,
|
||||
test_restore_snapshot_with_common_shareable_metadata_ids,
|
||||
test_restore_snapshot_with_markdown_file,
|
||||
test_restore_snapshot_with_settings_page,
|
||||
// TODO(kevin): figure out why the file name doesn't match.
|
||||
#[ignore]
|
||||
test_restore_snapshot_with_code_file,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_multi_block_selections,
|
||||
test_input_focused_after_executing_command,
|
||||
// TODO(alokedesai): Determine why this test doesn't reliably pass on CI.
|
||||
#[cfg_attr(target_os="linux", ignore)]
|
||||
test_with_launch_config,
|
||||
test_command_xray_hover,
|
||||
test_command_xray_for_partial_command,
|
||||
test_ctrl_r_multi_cursor,
|
||||
test_session_navigation_recency_change_tab,
|
||||
test_session_navigation_recency_navigate_to_tab,
|
||||
// Temporarily disable while we investigate why this test is failing on CI.
|
||||
#[ignore]
|
||||
test_session_navigation_recency_click_on_window,
|
||||
// TODO: Figure out why it is flakey.
|
||||
#[ignore]
|
||||
test_session_navigation_recency_navigate_to_window,
|
||||
test_block_based_snackbar_scroll_to_top,
|
||||
test_block_based_snackbar_small_window,
|
||||
test_block_based_snackbar_appears_for_running_command_input_at_bottom,
|
||||
test_block_based_snackbar_not_visible_for_pager_command_input_at_bottom,
|
||||
test_block_based_snackbar_appears_for_running_command_pinned_to_top,
|
||||
test_block_based_snackbar_not_visible_for_pager_command_pinned_to_top,
|
||||
test_block_based_snackbar_appears_for_running_command_waterfall_mode,
|
||||
test_block_based_snackbar_not_visible_pager_command_waterfall_mode,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_accepting_completion_inserts_space,
|
||||
test_palette_opens_when_theme_chooser_is_open,
|
||||
test_launch_warp_with_theme_in_warp_config,
|
||||
#[cfg(target_os="macos")]
|
||||
test_preview_config_dir_migration,
|
||||
#[ignore = "Flakes in CI"]
|
||||
test_add_launch_config_to_warp_config,
|
||||
#[ignore = "Flakes in CI"]
|
||||
test_add_workflows_to_warp_config,
|
||||
#[ignore = "Flakes in CI"]
|
||||
test_add_theme_to_warp_config,
|
||||
test_loading_project_workflows,
|
||||
test_completions_as_you_type,
|
||||
test_completions_as_you_type_one_matching_entry_tab,
|
||||
test_completions_as_you_type_execute_on_enter,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_cmd_enter,
|
||||
test_alias_expansion_has_limit,
|
||||
test_command_corrections,
|
||||
test_new_window_inherits_previous_session_directory,
|
||||
test_preferred_shell,
|
||||
test_open_new_tab_with_specific_shell_from_new_session_menu,
|
||||
test_open_launch_config_from_add_tab_menu_legacy,
|
||||
test_open_launch_config_with_custom_size,
|
||||
test_launch_config_single_child_branch,
|
||||
test_open_launch_config_in_active_window,
|
||||
test_with_launch_config_with_active_tab_index,
|
||||
test_with_launch_config_with_active_pane,
|
||||
test_with_launch_config_with_no_active_pane,
|
||||
test_find_query_not_evaluated_on_terminal_mode_change,
|
||||
test_custom_open_completions_menu_binding,
|
||||
test_ssh_with_shell_override,
|
||||
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_copy_prompt_from_block_honor_ps1_disabled,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_copy_prompt_from_input_honor_ps1_disabled,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_rprompt_doesnt_show_when_not_enough_space,
|
||||
test_block_cursor_navigation_using_escape_codes,
|
||||
test_block_bulk_deletion_using_escape_codes,
|
||||
test_escape_sequences_sent_to_focused_terminal,
|
||||
test_open_input_context_menu,
|
||||
test_copy_all_from_input_context_menu,
|
||||
test_cut_paste_from_input_context_menu,
|
||||
test_paste_and_type_characters_before_bootstrap,
|
||||
#[ignore = "Flaking on CI - KC looking into 3/31/26"]
|
||||
test_code_review_scroll_anchor_preserved_when_inserting_above,
|
||||
#[ignore = "Flaking on CI - KC looking into 3/31/26"]
|
||||
test_code_review_scroll_anchor_unchanged_when_inserting_below,
|
||||
#[ignore = "Flaking on CI - KC looking into 3/31/26"]
|
||||
test_code_review_scroll_preserved_second_file,
|
||||
#[ignore = "Flaking on CI - KC looking into 3/31/26"]
|
||||
test_code_review_scroll_preserved_deleted_range,
|
||||
#[ignore = "Flaking on CI - KC looking into 3/31/26"]
|
||||
test_code_review_scroll_preserved_header_range,
|
||||
#[ignore = "Flaking on CI - KC looking into 3/31/26"]
|
||||
test_code_review_scroll_preserved_footer_range,
|
||||
test_pane_group_state_single_pane,
|
||||
test_pane_group_state_multi_pane,
|
||||
test_pane_group_state_close_pane,
|
||||
test_pane_group_state_clear_blocks,
|
||||
|
||||
test_alt_screen_context_menu_with_sgr_with_mouse_reporting,
|
||||
test_alt_screen_context_menu_with_sgr_without_mouse_reporting,
|
||||
test_alt_screen_context_menu_without_sgr_with_mouse_reporting,
|
||||
test_alt_screen_context_menu_without_sgr_without_mouse_reporting,
|
||||
|
||||
test_input_syncing_is_off_by_default,
|
||||
test_can_sync_input_editor_text_in_tab,
|
||||
test_can_run_command_in_synced_panes_in_tab,
|
||||
test_synced_panes_long_running_commands,
|
||||
test_synced_inputs_terminal_mode_change_view_focus,
|
||||
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_can_bootstrap_remote_bash_subshell,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_can_bootstrap_remote_zsh_subshell,
|
||||
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_can_auto_bootstrap,
|
||||
|
||||
// Disabled due to flakiness on CI.
|
||||
#[ignore]
|
||||
test_create_session_with_split_pane_while_bootstrapping,
|
||||
|
||||
// For some reason, disabling the `AgentMode` flag does not actually disable Agent Mode in the test
|
||||
// run. Ignore for now.
|
||||
#[ignore]
|
||||
test_ask_warp_ai_keybinding_for_selected_block,
|
||||
|
||||
test_create_folder_from_command_palette,
|
||||
|
||||
test_tab_behavior_setting,
|
||||
|
||||
test_private_public_settings_routing_with_flag_enabled,
|
||||
test_private_settings_preloaded_and_not_leaked_to_toml,
|
||||
test_history_command_is_linked_to_local_workflow,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_up_arrow_history_enters_shift_tab_for_workflow,
|
||||
|
||||
test_websocket_begins_on_startup,
|
||||
test_websocket_does_not_begin_on_startup,
|
||||
test_websocket_begins_after_joining_a_team,
|
||||
test_websocket_begins_after_creating_an_object,
|
||||
|
||||
test_secret_is_obfuscated_on_copy,
|
||||
test_secret_tooltip_respects_safe_mode_setting,
|
||||
test_copy_secret_respects_safe_mode_setting,
|
||||
test_alt_screen_secret_detection,
|
||||
test_secret_case_sensitivity,
|
||||
test_secrets_are_always_redacted_in_ai_inputs,
|
||||
|
||||
test_active_session_follows_focus,
|
||||
|
||||
test_focus_panes_on_hover,
|
||||
|
||||
test_close_tab_with_long_running_process,
|
||||
|
||||
test_restore_single_closed_pane,
|
||||
test_restore_multiple_closed_panes,
|
||||
test_undo_close_grace_period_cleanup,
|
||||
test_closed_panes_cleared_on_rearrangement,
|
||||
test_tab_closes_when_last_visible_pane_closed,
|
||||
|
||||
test_notebook_pane_tracking,
|
||||
test_close_notebook_tab,
|
||||
test_open_in_warp_banner,
|
||||
test_close_notebook_window,
|
||||
test_backspace_inside_rendered_mermaid_block_is_atomic,
|
||||
|
||||
test_open_workflow_in_pane,
|
||||
test_create_personal_workflow_pane_from_command_palette,
|
||||
test_create_team_workflow_pane_from_command_palette,
|
||||
|
||||
// TODO(alokedesai): Fix this on the latest version of Bash.
|
||||
#[ignore]
|
||||
test_up_arrow_history,
|
||||
|
||||
test_block_filtering_keybinding,
|
||||
test_block_filtering_toolbelt_icon,
|
||||
test_block_filtering_context_menu,
|
||||
test_block_filtering_toggle_filter,
|
||||
test_block_filtering_toggle_filter_while_find_active,
|
||||
test_block_filtering_filter_then_find,
|
||||
test_block_filtering_with_secrets,
|
||||
test_block_filtering_active_block,
|
||||
test_block_filtering_clear_blocklist,
|
||||
test_autosuggestions_are_hidden_when_opening_tab_completions,
|
||||
test_latest_buffer_operations,
|
||||
|
||||
test_pass_control_sequences_to_long_running_block,
|
||||
test_settings_file_migration_from_native_store,
|
||||
test_settings_file_hot_reload_applies_new_values,
|
||||
|
||||
test_settings_error_banner_on_startup_with_invalid_toml,
|
||||
test_settings_error_banner_on_startup_with_invalid_value,
|
||||
test_settings_error_banner_on_reload_with_invalid_toml,
|
||||
test_settings_error_banner_on_reload_with_invalid_value,
|
||||
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_first_to_last_through_ai_simple,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_copy_on_select_first_to_last_through_ai_simple,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_first_to_last_through_ai_semantic,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_first_to_last_through_ai_lines,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_last_to_first_through_ai_simple,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_last_to_first_through_ai_semantic,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_last_to_first_through_ai_lines,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_first_to_ai_simple,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_first_to_ai_semantic,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_first_to_ai_lines,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_ai_to_first_simple,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_ai_to_first_semantic,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_ai_to_first_lines,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_ai_to_last_simple,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_ai_to_last_semantic,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_ai_to_last_lines,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_last_to_ai_simple,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_last_to_ai_semantic,
|
||||
#[ignore = "Affected by agent_view feature flag UI changes"]
|
||||
test_selection_last_to_ai_lines,
|
||||
test_restored_ai_block_renders_mermaid_and_local_images,
|
||||
|
||||
// Middle-click-paste is only implemented for Linux right now.
|
||||
#[cfg(target_os = "linux")]
|
||||
test_middle_click_paste,
|
||||
test_agent_mode_pane_minimum_size,
|
||||
|
||||
test_rule_creation,
|
||||
test_rule_update,
|
||||
test_rule_pane_opening,
|
||||
test_undo_close_stack_timeout_cleanup,
|
||||
|
||||
test_file_tree_opens_files_in_warp,
|
||||
test_file_tree_open_in_new_pane,
|
||||
test_file_tree_open_in_new_tab,
|
||||
test_file_tree_keyboard_navigation,
|
||||
test_file_tree_non_openable_files,
|
||||
test_file_tree_nested_file_opening,
|
||||
|
||||
// Go to Line tests
|
||||
test_goto_line_dialog_open_close,
|
||||
test_goto_line_jumps_to_line,
|
||||
test_goto_line_with_column,
|
||||
test_goto_line_clamps_out_of_range,
|
||||
|
||||
// Keyboard protocol tests
|
||||
test_keyboard_protocol_disabled_shift_enter,
|
||||
test_keyboard_protocol_enabled_shift_enter,
|
||||
test_keyboard_protocol_enabled_shifted_symbol_uses_unshifted_keycode,
|
||||
test_keyboard_protocol_query_and_apply_modes,
|
||||
test_keyboard_protocol_report_all_keys_printable_and_cursor,
|
||||
test_keyboard_protocol_event_types,
|
||||
test_keyboard_protocol_modifier_key_reporting,
|
||||
test_keyboard_protocol_modifier_self_bit,
|
||||
test_keyboard_protocol_alternate_keys_and_text,
|
||||
|
||||
// Video recording test — requires real display, run manually
|
||||
#[ignore = "Manual test: requires real display for frame capture"]
|
||||
test_video_recording,
|
||||
}
|
||||
Reference in New Issue
Block a user