diff --git a/src/wrappers/error-wrapper.js b/src/wrappers/error-wrapper.js index 16fe1e8bc..a75cc1f14 100644 --- a/src/wrappers/error-wrapper.js +++ b/src/wrappers/error-wrapper.js @@ -12,6 +12,14 @@ export default class ErrorWrapper implements BaseWrapper { throwError(`find did not return ${this.selector}, cannot call at() on empty Wrapper`) } + attributes (): void { + throwError(`find did not return ${this.selector}, cannot call attributes() on empty Wrapper`) + } + + classes (): void { + throwError(`find did not return ${this.selector}, cannot call classes() on empty Wrapper`) + } + contains (): void { throwError(`find did not return ${this.selector}, cannot call contains() on empty Wrapper`) } @@ -72,6 +80,10 @@ export default class ErrorWrapper implements BaseWrapper { throwError(`find did not return ${this.selector}, cannot call name() on empty Wrapper`) } + props (): void { + throwError(`find did not return ${this.selector}, cannot call props() on empty Wrapper`) + } + text (): void { throwError(`find did not return ${this.selector}, cannot call text() on empty Wrapper`) } diff --git a/src/wrappers/wrapper-array.js b/src/wrappers/wrapper-array.js index 8cbddbd0d..03be500d1 100644 --- a/src/wrappers/wrapper-array.js +++ b/src/wrappers/wrapper-array.js @@ -20,6 +20,18 @@ export default class WrapperArray implements BaseWrapper { return this.wrappers[index] } + attributes (): void { + this.throwErrorIfWrappersIsEmpty('attributes') + + throwError('attributes must be called on a single wrapper, use at(i) to access a wrapper') + } + + classes (): void { + this.throwErrorIfWrappersIsEmpty('classes') + + throwError('classes must be called on a single wrapper, use at(i) to access a wrapper') + } + contains (selector: Selector): boolean { this.throwErrorIfWrappersIsEmpty('contains') @@ -107,6 +119,12 @@ export default class WrapperArray implements BaseWrapper { throwError('name must be called on a single wrapper, use at(i) to access a wrapper') } + props (): void { + this.throwErrorIfWrappersIsEmpty('props') + + throwError('props must be called on a single wrapper, use at(i) to access a wrapper') + } + text (): void { this.throwErrorIfWrappersIsEmpty('text') diff --git a/src/wrappers/wrapper.js b/src/wrappers/wrapper.js index a298a3fbd..b8fd62d8e 100644 --- a/src/wrappers/wrapper.js +++ b/src/wrappers/wrapper.js @@ -33,6 +33,38 @@ export default class Wrapper implements BaseWrapper { throwError('at() must be called on a WrapperArray') } + /** + * Returns an Object containing all the attribute/value pairs on the element. + */ + attributes (): { [name: string]: string } { + const attributes = [...this.element.attributes] // NameNodeMap is not iterable + const attributeMap = {} + attributes.forEach((att) => { + attributeMap[att.localName] = att.value + }) + return attributeMap + } + + /** + * Returns an Array containing all the classes on the element + */ + classes (): Array { + let classes = [...this.element.classList] + // Handle converting cssmodules identifiers back to the original class name + if (this.vm && this.vm.$style) { + const cssModuleIdentifiers = {} + let moduleIdent + Object.keys(this.vm.$style).forEach((key) => { + moduleIdent = this.vm.$style[key] + // CSS Modules may be multi-class if they extend others. Extended classes should be already present in $style. + moduleIdent = moduleIdent.split(' ')[0] + cssModuleIdentifiers[moduleIdent] = key + }) + classes = classes.map(className => cssModuleIdentifiers[className] || className) + } + return classes + } + /** * Checks if wrapper contains provided selector. */ @@ -309,6 +341,23 @@ export default class Wrapper implements BaseWrapper { return this.vnode.tag } + /** + * Returns an Object containing the prop name/value pairs on the element + */ + props (): { [name: string]: any } { + if (!this.isVueComponent) { + throwError('wrapper.props() must be called on a Vue instance') + } + // $props object does not exist in Vue 2.1.x, so use $options.propsData instead + let _props + if (this.vm && this.vm.$options && this.vm.$options.propsData) { + _props = this.vm.$options.propsData + } else { + _props = this.vm.$props + } + return _props || {} // Return an empty object if no props exist + } + /** * Sets vm data */ diff --git a/test/resources/components/component-with-css-modules.vue b/test/resources/components/component-with-css-modules.vue index 93a017026..95b6efb56 100644 --- a/test/resources/components/component-with-css-modules.vue +++ b/test/resources/components/component-with-css-modules.vue @@ -1,11 +1,16 @@