diff --git a/src/ShallowTraversal.js b/src/ShallowTraversal.js index 49f3c44d0..95a490425 100644 --- a/src/ShallowTraversal.js +++ b/src/ShallowTraversal.js @@ -110,10 +110,13 @@ export function buildPredicate(selector) { return node => nodeHasId(node, selector.slice(1)); case SELECTOR.PROP_TYPE: { - const propKey = selector.split(/\[([a-zA-Z-]*?)(=|])/)[1]; + const propKey = selector.split(/\[([a-z]+[a-z-0-9-]*?)(=|])/i); + if (propKey.length === 1) { + throw new TypeError(`Enzyme::Invalid attribute selector ('${selector}')`); + } const propValue = selector.split(/=(.*?)]/)[1]; - return node => nodeHasProperty(node, propKey, propValue); + return node => nodeHasProperty(node, propKey[1], propValue); } default: // selector is a string. match to DOM tag or constructor displayName diff --git a/test/ShallowWrapper-spec.jsx b/test/ShallowWrapper-spec.jsx index abdb8f486..248df52ec 100644 --- a/test/ShallowWrapper-spec.jsx +++ b/test/ShallowWrapper-spec.jsx @@ -565,6 +565,36 @@ describe('shallow', () => { expect(wrapper.find('a[value=true]')).to.have.length(0); }); + it('should support attributes with numbers', () => { + const wrapper = shallow( +
, + ); + + expect(wrapper.find('span[value-1=1]')).to.have.length(1); + expect(wrapper.find('a[value-1=false]')).to.have.length(1); + }); + + it('throws if when selector is invalid', () => { + const wrapper = shallow( + , + ); + expect(() => wrapper.find('span[1-foo=1]')).to.throw( + TypeError, + 'Enzyme::Invalid attribute selector', + ); + expect(() => wrapper.find('span[1foo=1]')).to.throw( + TypeError, + 'Enzyme::Invalid attribute selector', + ); + expect(() => wrapper.find('span[^^^=1]')).to.throw( + TypeError, + 'Enzyme::Invalid attribute selector', + ); + }); + it('should not find key or ref via property selector', () => { const arrayOfComponents = [, ];