diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6cb2cd..3c81bc6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: node-version: '22' - uses: browser-actions/setup-chrome@v2 with: - chrome-version: '144' + chrome-version: '146' install-chromedriver: true - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 @@ -138,7 +138,7 @@ jobs: node-version: '22' - uses: browser-actions/setup-chrome@v2 with: - chrome-version: '143' + chrome-version: '146' install-chromedriver: true - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 @@ -186,7 +186,7 @@ jobs: node-version: '22' - uses: browser-actions/setup-chrome@v2 with: - chrome-version: '144' + chrome-version: '146' install-chromedriver: true - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 diff --git a/README.md b/README.md index 1976ea6..5a79e82 100644 --- a/README.md +++ b/README.md @@ -242,8 +242,9 @@ How to develop 1. Run `npm install` to install all dependencies. 2. Change the target database URL in `tanin.backdoor.BackdoorServier.main(..)` -2. Run `./gradlew run` in order to run the web server. +2. Run `./gradlew web:run` in order to run the web server. 3. On a separate terminal, run `npm run hmr` in order to hot-reload the frontend code changes. +4. Visit http://localhost:9090 and login with `masked_test` and `1234` How to run tests ----------------- @@ -256,9 +257,10 @@ How to run tests - The username is `backdoor_test`. - The password is `test_ch` -1. Run `npm install` to install all dependencies. -3. On a separate terminal, run `npm run hmr`. -2. Run `./gradlew test` in order to run all the tests. +3. Run `npm install` to install all dependencies. +4. On a separate terminal, run `npm run hmr`. +5. Start the ClickHouse server by running `clickhouse server`. +6. Run `./gradlew test` in order to run all the tests. Publish JAR ------------ diff --git a/core/src/test/java/tanin/backdoor/Base.java b/core/src/test/java/tanin/backdoor/Base.java index 14d553d..b50e050 100644 --- a/core/src/test/java/tanin/backdoor/Base.java +++ b/core/src/test/java/tanin/backdoor/Base.java @@ -298,7 +298,7 @@ void retryInteraction(VoidFn fn) throws InterruptedException { try { fn.invoke(); return; - } catch (ElementNotInteractableException ex) { + } catch (ElementNotInteractableException | StaleElementReferenceException ex) { Thread.sleep(1000); } } diff --git a/core/src/test/java/tanin/backdoor/postgres/TableTest.java b/core/src/test/java/tanin/backdoor/postgres/TableTest.java index 254ad0a..1e4272d 100644 --- a/core/src/test/java/tanin/backdoor/postgres/TableTest.java +++ b/core/src/test/java/tanin/backdoor/postgres/TableTest.java @@ -305,7 +305,7 @@ void deleteRow() throws InterruptedException { } @Test - void filterRowSpecificValue() throws InterruptedException { + void filterRowSpecificValueAndClearFilter() throws InterruptedException { go("/"); click(tid("database-item")); waitUntil(() -> assertEquals("loaded", elem(tid("database-item")).getDomAttribute("data-database-status"))); @@ -321,6 +321,43 @@ void filterRowSpecificValue() throws InterruptedException { click(tid("submit-button")); waitUntil(() -> assertColumnValues("username", "test_user_2")); + + click(tid("clear-all-filters-button")); + waitUntil(() -> assertColumnValues("username", "test_user_1", "test_user_2", "test_user_3", "test_user_4")); + } + + @Test + void theCurrentFilterValueDoesNotSpillOver() throws InterruptedException { + go("/"); + click(tid("database-item")); + waitUntil(() -> assertEquals("loaded", elem(tid("database-item")).getDomAttribute("data-database-status"))); + + + click(tid("menu-items", "postgres", null, "menu-item-table", "user")); + + waitUntil(() -> assertTrue(hasElem(tid("sheet-tab", "user")))); + click(tid("sheet-view-column-header", "username", null, "filter-button")); + + click(tid("specified-value-checkbox")); + fill(tid("specified-value-input"), "test_user_2"); + click(tid("submit-button")); + + waitUntil(() -> assertColumnValues("username", "test_user_2")); + + click(tid("sheet-view-column-header", "password", null, "filter-button")); + + click(tid("specified-value-checkbox")); + fill(tid("specified-value-input"), "password2"); + click(tid("submit-button")); + + waitUntil(() -> assertColumnValues("username", "test_user_2")); + + click(tid("sheet-view-column-header", "username", null, "filter-button")); + waitUntil(() -> assertEquals("test_user_2", elem(tid("specified-value-input")).getDomProperty("value"))); + click(tid("cancel-button")); + + click(tid("sheet-view-column-header", "password", null, "filter-button")); + waitUntil(() -> assertEquals("password2", elem(tid("specified-value-input")).getDomProperty("value"))); } @Test diff --git a/frontend/svelte/_filter_modal.svelte b/frontend/svelte/_filter_modal.svelte index 7c2d131..cab35cf 100644 --- a/frontend/svelte/_filter_modal.svelte +++ b/frontend/svelte/_filter_modal.svelte @@ -45,6 +45,7 @@ export function open(column: Column): void { mode = 'not_null' } else if (filter.operator === 'EQUAL') { mode = 'specified_value' + specifiedValue = filter.value } else { throw new Error(`Unrecognized column '${filter.operator}'`) } @@ -218,7 +219,9 @@ async function submit() { - +