Skip to content

Commit

Permalink
Added additional setter methods for select lists
Browse files Browse the repository at this point in the history
  • Loading branch information
nbeach committed Apr 14, 2020
1 parent c23c825 commit 163a2d8
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,26 @@ setTextAreaValue(element("textarea"), "Sasquatch") //Text area now has value "Sa
setCheckboxValue(element("input[type=check]"), true) //Checkbox is now checked
setRadioButton(element("input[type=radio]"), true) //Radio button is now selected
setSelectValue(element("select"), "Hancock") //Dropdown list now has the value "Hancock" selected
setSelectIndex(element("select"), 1) //Dropdown list now has the second option selected

```

These work with any DOM element reference, not just those returned by ng-units selection methods. They can be used
in traditional TestBed tests if desired.

#### Select lists and `[ngValue]`
Using `[ngValue]` for select list option bindings complicates setting a value slightly. The bound values can
types other than strings, and consequently the value is not bound to the DOM. This makes determining which option to select more complicated.

If you know the index of the option you want you can use `setSelectIndex(element("select"), index)` to select the value

If you have access to a list of all the options you can use `setSelectFromOptions()` to select the value:
```typescript
const listOptions = [{ message: "Hello"}, { message: "Goodbye"}]
setSelectFromOptions(element("select"), { message: "Goodbye"}, listOptions)
```


#### Setting component inputs
Initial values for component inputs can be set prior to component instantiation (so they are properly present at
OnInit time) with the test builder method`.setInput()`.
Expand Down
113 changes: 113 additions & 0 deletions src/dom.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
selectComponents,
setCheckboxValue,
setRadioButton,
setSelectFromOptions,
setSelectIndex,
setSelectValue,
setTextAreaValue,
setTextInputValue,
Expand Down Expand Up @@ -119,6 +121,117 @@ describe("DOM", () => {
expect(subject.selectValue).to.equal("Adios")
})


})

describe("setSelectIndex() sets the value of select elements", () => {

it("when options have value attributes", () => {
@Component({
selector: "parent",
template: `
<select [(ngModel)]="selectValue">
<option></option>
<option value="Hola">Hello</option>
<option value="Adios">Goodbye</option>
</select>
`,
})
class TestComponent {
public selectValue = ""
}
const {subject, subjectElement, fixture} = setupTestModule(TestComponent)


setSelectIndex(subjectElement.querySelector("select"), 2)
fixture.detectChanges()

expect(subject.selectValue).to.equal("Adios")
})

it("when options have ngValue attributes", () => {
@Component({
selector: "parent",
template: `
<select [(ngModel)]="selectValue">
<option [ngValue]="null"></option>
<option [ngValue]="{ message: 'Hola' }">Hello</option>
<option [ngValue]="{ message: 'Adios' }">Goodbye</option>
</select>
`,
})
class TestComponent {
public selectValue = null
}
const {subject, subjectElement, fixture} = setupTestModule(TestComponent)

setSelectIndex(subjectElement.querySelector("select"), 1)
fixture.detectChanges()
expect(subject.selectValue).to.deep.equal({ message: "Hola" })

setSelectIndex(subjectElement.querySelector("select"), 0)
fixture.detectChanges()
expect(subject.selectValue).to.equal(null)
})

})

describe("setSelectFromOptions() sets the value of select elements", () => {

it("when options have ngValue attributes", () => {
@Component({
selector: "parent",
template: `
<select [(ngModel)]="selectValue">
<option *ngFor="let option of allOptions" [ngValue]="option">{{option?.label}}</option>
</select>
`,
})
class TestComponent {
public allOptions = [
null,
{ label: "Hello", value: "Hola" },
{ bar: "Adios" },
]

public selectValue = null
}
const {subject, subjectElement, fixture} = setupTestModule(TestComponent)


setSelectFromOptions(subjectElement.querySelector("select"), { bar: "Adios" }, subject.allOptions)
fixture.detectChanges()

expect(subject.selectValue).to.deep.equal({ bar: "Adios" })
})

it("when options have value attributes", () => {
@Component({
selector: "parent",
template: `
<select [(ngModel)]="selectValue">
<option *ngFor="let option of allOptions" value="{{option?.value}}">{{option?.label}}</option>
</select>
`,
})
class TestComponent {
public allOptions = [
null,
{ label: "Hello", value: "Hola" },
{ label: "Goodbye", value: "Adios" },
]

public selectValue = null
}
const {subject, subjectElement, fixture} = setupTestModule(TestComponent)


setSelectFromOptions(subjectElement.querySelector("select"), { label: "Goodbye", value: "Adios" }, subject.allOptions)
fixture.detectChanges()

expect(subject.selectValue).to.equal("Adios")
})

})

it('setRadioButton() sets the value of <input type="radio"> elements', () => {
Expand Down
15 changes: 15 additions & 0 deletions src/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {isNil, isString, findIndex} from "lodash"
import {By} from "@angular/platform-browser"
import {selectorOf} from "./selector-of"
import {Type} from "@angular/core"
import { isEqual } from "lodash"

function doIfElementPresent<T>(element: T | null, action: (item: T) => void) {
if (isNil(element)) {
Expand Down Expand Up @@ -30,6 +31,20 @@ export function setSelectValue(selectBox: Element | null, value: string): void {
})
}

export function setSelectIndex(selectBox: Element | null, index: number): void {
doIfElementPresent(selectBox, selectBox => {
(selectBox as any).selectedIndex = index
trigger(selectBox, "change")
})
}

export function setSelectFromOptions(selectBox: Element | null, optionToSelection: any, allOptions: any[]): void {
doIfElementPresent(selectBox, selectBox => {
(selectBox as any).selectedIndex = findIndex(allOptions, option => isEqual(option, optionToSelection))
trigger(selectBox, "change")
})
}

export const setTextAreaValue = setTextInputValue

export function setCheckboxValue(input: Element | null, checked: boolean): void {
Expand Down

0 comments on commit 163a2d8

Please sign in to comment.