Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
203 changes: 201 additions & 2 deletions packages/main/cypress/specs/Input.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1964,7 +1964,7 @@ describe("Input general interaction", () => {
.should("be.focused");

cy.get("@inputEl")
.realType("a");
.realType("A");

cy.get("@inputEl")
.should("have.value", "Adam D");
Expand All @@ -1985,7 +1985,7 @@ describe("Input general interaction", () => {
);

cy.get("#input-custom-flat").shadow().find("input").as("input");
cy.get("@input").click().realType("a");
cy.get("@input").click().realType("A");

cy.get("@input").should("have.value", "Albania");
cy.get("@input").then($input => {
Expand Down Expand Up @@ -3227,4 +3227,203 @@ describe("Input built-in filtering", () => {
.eq(1)
.should("have.attr", "hidden");
});

describe("Typeahead capitalization handling", () => {
it("should preserve user's typed capitalization during typeahead and use original suggestion capitalization when accepted", () => {
cy.mount(
<Input id="capitalization-test" showSuggestions>
<SuggestionItem text="Apple" />
<SuggestionItem text="Apricot" />
<SuggestionItem text="Avocado" />
</Input>
);

cy.get("#capitalization-test")
.shadow()
.find("input")
.as("input");

// Type lowercase 'a' - should show 'apple' with user's lowercase 'a'
cy.get("@input")
.realClick()
.realType("a");

cy.get("@input")
.should("have.value", "apple");

// Verify text selection (typeahead highlighting)
cy.get("@input")
.then($input => {
const input = $input[0] as HTMLInputElement;
expect(input.selectionStart).to.equal(1);
expect(input.selectionEnd).to.equal(5);
});

// Press Enter to accept - should use original suggestion capitalization "Apple"
cy.realPress("Enter");

cy.get("@input")
.should("have.value", "Apple");
});

it("should preserve uppercase typed letters during typeahead", () => {
cy.mount(
<Input id="capitalization-test-upper" showSuggestions>
<SuggestionItem text="apple" />
<SuggestionItem text="apricot" />
</Input>
);

cy.get("#capitalization-test-upper")
.shadow()
.find("input")
.as("input");

// Type uppercase 'A' - should show 'Apple' with user's uppercase 'A'
cy.get("@input")
.realClick()
.realType("A");

cy.get("@input")
.should("have.value", "Apple");

// Press Enter to accept - should use original suggestion capitalization "apple"
cy.realPress("Enter");

cy.get("@input")
.should("have.value", "apple");
});

it("should match suggestions regardless of capitalization and use original on Enter", () => {
cy.mount(
<Input id="exact-match-test" showSuggestions>
<SuggestionItem text="ap" />
<SuggestionItem text="Apple" />
</Input>
);

cy.get("#exact-match-test")
.shadow()
.find("input")
.as("input");

// Type "Ap" matching suggestion "ap"
cy.get("@input")
.realClick()
.realType("Ap");

// During typing, user's capitalization is preserved
cy.get("@input")
.should("have.value", "Ap");

// Press Enter - should use original suggestion capitalization "ap"
cy.realPress("Enter");

cy.get("@input")
.should("have.value", "ap");
});

it("should preserve user's typed capitalization through multiple characters", () => {
cy.mount(
<Input id="multi-char-test" showSuggestions>
<SuggestionItem text="BANANA" />
<SuggestionItem text="BERRY" />
</Input>
);

cy.get("#multi-char-test")
.shadow()
.find("input")
.as("input");

// Type "bAn" with mixed capitalization
cy.get("@input")
.realClick()
.realType("bAn");

// Should show suggestion with user's typed capitalization
cy.get("@input")
.should("have.value", "bAnANA");

// Press Enter - should use original suggestion capitalization "BANANA"
cy.realPress("Enter");

cy.get("@input")
.should("have.value", "BANANA");
});

it("should work with selection-change event and preserve original capitalization", () => {
const onChangeSpy = cy.spy().as("onChange");
const onSelectionChangeSpy = cy.spy().as("onSelectionChange");

cy.mount(
<Input
id="selection-change-test"
showSuggestions
onChange={onChangeSpy}
onSelectionChange={onSelectionChangeSpy}
>
<SuggestionItem text="Orange" />
<SuggestionItem text="Olive" />
</Input>
);

cy.get("#selection-change-test")
.shadow()
.find("input")
.as("input");

// Type lowercase 'o'
cy.get("@input")
.realClick()
.realType("o");

cy.get("@input")
.should("have.value", "orange");

// Press Enter to trigger selection-change
cy.realPress("Enter");

// Value should be original suggestion capitalization
cy.get("@input")
.should("have.value", "Orange");

// Verify both events were called
cy.get("@onChange").should("have.been.calledOnce");
cy.get("@onSelectionChange").should("have.been.calledOnce");
});

it("should clear matched item on Escape and restore typed value", () => {
cy.mount(
<Input id="escape-test" showSuggestions>
<SuggestionItem text="Apple" />
</Input>
);

cy.get("#escape-test")
.shadow()
.find("input")
.as("input");

// Type 'a' to trigger typeahead
cy.get("@input")
.realClick()
.realType("a");

cy.get("@input")
.should("have.value", "apple");

// Press Escape to cancel autocomplete
cy.realPress("Escape");

cy.get("@input")
.should("have.value", "a");

// Now press Enter - should not select anything
cy.realPress("Enter");

cy.get("@input")
.should("have.value", "a");
});
});
});
4 changes: 2 additions & 2 deletions packages/main/cypress/specs/Input.mobile.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ describe("Typeahead", () => {
.ui5ResponsivePopoverOpened();

cy.get("#myInput2").shadow().find(".ui5-input-inner-phone").should("be.focused");
cy.get("#myInput2").shadow().find(".ui5-input-inner-phone").realType("c");
cy.get("#myInput2").shadow().find(".ui5-input-inner-phone").realType("C");
cy.get("#myInput2").shadow().find(".ui5-input-inner-phone").should("have.value", "Cozy");
});

Expand Down Expand Up @@ -313,7 +313,7 @@ describe("Typeahead", () => {
.ui5ResponsivePopoverOpened();

cy.get("#input-custom-flat").shadow().find(".ui5-input-inner-phone").should("be.focused");
cy.get("#input-custom-flat").shadow().find(".ui5-input-inner-phone").realType("a");
cy.get("#input-custom-flat").shadow().find(".ui5-input-inner-phone").realType("A");
cy.get("#input-custom-flat").shadow().find(".ui5-input-inner-phone").should("have.value", "Albania");
});
});
Expand Down
2 changes: 1 addition & 1 deletion packages/main/cypress/specs/MultiComboBox.mobile.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ describe("Typeahead", () => {
.find("[ui5-input]")
.as("respPopoverInput")
.realClick()
.realType("c");
.realType("C");

cy.get("@respPopoverInput")
.should("have.value", "Cosy");
Expand Down
69 changes: 68 additions & 1 deletion packages/main/cypress/specs/MultiInput.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -575,11 +575,78 @@ describe("MultiInput tokens", () => {
.realClick();

cy.get("@input")
.type("b");
.type("B");

cy.get("[ui5-multi-input]")
.should("have.attr", "value", "Bulgaria");
});

it("should not select multiple suggestions when switching between typed values", () => {
cy.mount(
<MultiInput
id="multi-selection-test"
showSuggestions
placeholder="Type country name..."
>
<SuggestionItemCustom text="Bulgaria">
<span>Bulgaria</span>
</SuggestionItemCustom>
<SuggestionItemCustom text="Canada">
<span>Canada</span>
</SuggestionItemCustom>
<SuggestionItemCustom text="Germany">
<span>Germany</span>
</SuggestionItemCustom>
<SuggestionItemCustom text="Austria">
<span>Austria</span>
</SuggestionItemCustom>
</MultiInput>
);

cy.get("[ui5-multi-input]")
.shadow()
.find("input")
.as("input");

cy.get("@input")
.realClick()
.realType("Bul");

// Wait for popover to open
cy.get("[ui5-multi-input]")
.shadow()
.find<ResponsivePopover>("[ui5-responsive-popover]")
.ui5ResponsivePopoverOpened();

// Bulgaria is first item (index 0), check it's selected
cy.get("[ui5-multi-input]")
.find("[ui5-suggestion-item-custom]")
.eq(0)
.should("have.prop", "selected", true);

// Other items should not be selected
cy.get("[ui5-multi-input]")
.find("[ui5-suggestion-item-custom]")
.eq(1)
.should("have.prop", "selected", false);

// Clear and type "Cana"
cy.get("@input")
.clear()
.realType("Cana");

// Canada is second item (index 1), check it's selected
cy.get("[ui5-multi-input]")
.find("[ui5-suggestion-item-custom]")
.eq(1)
.should("have.prop", "selected", true);

// Bulgaria (index 0) should NOT be selected anymore
cy.get("[ui5-multi-input]")
.find("[ui5-suggestion-item-custom]")
.eq(0)
.should("have.prop", "selected", false);
});
});

describe("MultiInput Truncated Token", () => {
Expand Down
Loading
Loading