Skip to content

update setValue to work with any input type #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 3, 2020
53 changes: 50 additions & 3 deletions src/dom-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,14 @@ export class DOMWrapper<ElementType extends Element> implements WrapperAPI {
)
}

async setChecked(checked: boolean = true) {
private async setChecked(checked: boolean = true) {
// typecast so we get typesafety
const element = (this.element as unknown) as HTMLInputElement
const type = this.attributes().type

if (element.tagName !== 'INPUT') {
if (type === 'radio' && !checked) {
throw Error(
`You need to call setChecked on an input element. You called it on a ${this.element.tagName}`
`wrapper.setChecked() cannot be called with parameter false on a '<input type="radio" /> element.`
)
}

Expand All @@ -78,6 +79,52 @@ export class DOMWrapper<ElementType extends Element> implements WrapperAPI {
return this.trigger('change')
}

setValue(value?: any) {
const element = (this.element as unknown) as HTMLInputElement
const tagName = element.tagName
const type = this.attributes().type

if (tagName === 'OPTION') {
return this.setSelected()
} else if (tagName === 'INPUT' && type === 'checkbox') {
return this.setChecked(value)
} else if (tagName === 'INPUT' && type === 'radio') {
return this.setChecked(value)
} else if (
tagName === 'INPUT' ||
tagName === 'TEXTAREA' ||
tagName === 'SELECT'
) {
element.value = value

if (tagName === 'SELECT') {
return this.trigger('change')
}
this.trigger('input')
// trigger `change` for `v-model.lazy`
return this.trigger('change')
} else {
throw Error(`wrapper.setValue() cannot be called on ${tagName}`)
}
}

private setSelected() {
const element = (this.element as unknown) as HTMLOptionElement

if (element.selected) {
return
}

element.selected = true
let parentElement = element.parentElement

if (parentElement.tagName === 'OPTGROUP') {
parentElement = parentElement.parentElement
}

return new DOMWrapper(parentElement).trigger('change')
}

async trigger(eventString: string) {
const evt = document.createEvent('Event')
evt.initEvent(eventString)
Expand Down
8 changes: 8 additions & 0 deletions src/error-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export class ErrorWrapper {
return Error(`Cannot call ${method} on an empty wrapper.`)
}

attributes() {
throw this.wrapperError('attributes')
}

classes() {
throw this.wrapperError('classes')
}
Expand All @@ -34,6 +38,10 @@ export class ErrorWrapper {
throw this.wrapperError('setChecked')
}

setValue() {
throw this.wrapperError('setValue')
}

text() {
throw this.wrapperError('text')
}
Expand Down
4 changes: 0 additions & 4 deletions src/vue-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,6 @@ export class VueWrapper implements WrapperAPI {
return Array.from(results).map((x) => new DOMWrapper(x))
}

async setChecked(checked: boolean = true) {
return new DOMWrapper(this.element).setChecked(checked)
}

trigger(eventString: string) {
const rootElementWrapper = new DOMWrapper(this.element)
return rootElementWrapper.trigger(eventString)
Expand Down
3 changes: 3 additions & 0 deletions tests/components/ComponentWithInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
value="radioBarResult"
/>
<input type="text" v-model="textVal" />
<input id="lazy" type="text" v-model.lazy="lazy" />
<textarea v-model="textareaVal"></textarea>
<select v-model="selectVal">
<option value="selectA"></option>
Expand All @@ -36,6 +37,7 @@
{{ textVal }}
{{ selectVal }}
{{ radioVal }}
{{ lazy }}
</div>
</template>

Expand All @@ -49,6 +51,7 @@ export default defineComponent({
return {
checkboxVal: undefined,
textVal: undefined,
lazy: undefined,
textareaVal: undefined,
radioVal: undefined,
selectVal: undefined,
Expand Down
105 changes: 0 additions & 105 deletions tests/setChecked.spec.ts

This file was deleted.

Loading