Use testing-library to get elements from third-party libs - javascript

I have a Vue 2 project that uses v-calendar and I'd like to test it using #testing-library/vue.
The library encourages you to use getByRole and specify a name to narrow down the results but here I can't since the DOM comes from an external library.
I can't either use getByTestId for the same reason.
The content of the button is an SVG so getByText is not possible neither.
Is it ok in this specific case to use the container returned from the render method and do container.querySelector('vc-nav-arrow is-left')?
<div role="button" class="vc-arrow is-left">
<svg data-v-63f7b5ec="" width="26px" height="26px" viewBox="0 -1 16 34" class="vc-svg-icon"><path data-v-63f7b5ec="" d="M11.196 10c0 0.143-0.071 0.304-0.179 0.411l-7.018 7.018 7.018 7.018c0.107 0.107 0.179 0.268 0.179 0.411s-0.071 0.304-0.179 0.411l-0.893 0.893c-0.107 0.107-0.268 0.179-0.411 0.179s-0.304-0.071-0.411-0.179l-8.321-8.321c-0.107-0.107-0.179-0.268-0.179-0.411s0.071-0.304 0.179-0.411l8.321-8.321c0.107-0.107 0.268-0.179 0.411-0.179s0.304 0.071 0.411 0.179l0.893 0.893c0.107 0.107 0.179 0.25 0.179 0.411z"></path></svg>
</div>

Related

How to load SVG from file/url and display as React component

I want to load an SVG from a file or through a URL and then use it as a React component.
I've tried many ways, but I can't figure out to do that correctly.
Can someone give me a hint to achieve it?
Currently I'm creating components this way, but as I mentioned, it should be at runtime loaded from a file instead:
const SvgComponent = (props) => (
<svg
height={800}
width={800}
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
xmlSpace="preserve"
{...props}
>
<path
fill={props.color || '#000'}
d="M23 24H3v-2h18V6.4L16.6 2H5v7H3V0h14.4L23 5.6z"
/>
<path
fill={props.color || '#000'}
d="M22 8h-7V2h2v4h5zM4.8 15.4l-3-4.4h2.3L6 13.9 7.9 11h2.3l-3 4.4 3.1 4.6H8l-2-3.1L4 20H1.7l3.1-4.6z"
/>
</svg>
)
For a URL, you'd just use the image tag <img src={svgUrl} ...>
I suppose you could also fetch or read from file the SVG data as you would any other data and render it {svgData}.
You can use FileReader's readAsDataURL and set the result to an image's src, or read the file (or fetch the data) an use <img src={URL.createObjectURL(photoData)} alt={photoName} /> or similar.

How to check if array is empty in handlebar templates?(ember js)

I have template, which contains simple icon template:
<span class="icon {{unbound pperson.medical.diseases '=' 0 'hidden'}}">
<img class="icon" src="/assets/img/icons/icon.svg
</span>
As can be seen I need a flag to show/display it and I'm using hidden class for it. And I have data-array 'diseases'. So if it's empty I should not display icon, if it's not empty I should display this icon. I tried condition:
{unbound pperson.medical.diseases '=' 0 'hidden'}}
This gives error. I found that it was possible to write ember handle bar function and to use but I would like to find inline approach without creating aditional functions. is it possible?
Seems I found solution. Probably on page load diseaseases didn't exist so I added null-undefined check. not it seems to be working
<span class="icon {{unbound (unless (or null-undefined pperson.medical.disease pperson.medical.diseases.length '=' 0 ) 'hidden')}}">
Ember considers an empty array as falsely. So you should be able to do this:
<span class="icon {{unless pperson.medical.diseases 'hidden'}}">
<img class="icon" src="/assets/img/icons/icon.svg
</span>
Personally I feel that relying on the different truthiness of Handlebars templates compared to regular JavaScript makes the code more difficult to read. And Ember.js may change the template syntax to match JavaScript truthiness more closer. So I would recommend checking the length of the array instead. 0 is considered falsely just as in JavaScript.
<span class="icon {{unless pperson.medical.diseases.length 'hidden'}}">
<img class="icon" src="/assets/img/icons/icon.svg
</span>
The {{unbound}} helper is only needed if you want to prevent your template reflecting changes in application state. {{unbound pperson.medical.diseases}} would cause the user interface not to change if items are added or removed from diseases array. This is nearly never what you want. The official template linting rules forbid usage of {{unbound}} as part of their recommended set.
{{unbound pperson.medical.diseases '=' 0 'hidden'}} is not a valid statement assuming that you haven't overloaded the default {{unbound}} template helper. I assume that you are missing something an {{if}} or {{unless}} condition in that snippet and a custom helper, which supports comparison with pperson.medical.diseases '=' 0.

How can I make URL action work from a vue component

I'm working on a small project with ASP.NET MVC and VueJs. I created some components and added them to the Project.js file like so:
<div class="card_four">
<a href="#Url.Action('LoanRequest', 'LoanOrigination')">APPLY NOW
<i class="icon">
<svg width="8" height="13" viewBox="0 0 8 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.584961 11.5841L5.17099 6.99807L0.584961 2.41205L1.99896 0.998047L7.99899 6.99807L1.99896 12.9981L0.584961 11.5841Z" fill="white"></path>
</svg>
</i>
</a>
<p>No collateral Needed</p>
</div>
When I clicked on the link, the asp.net MVC URL link broke. How can I rewrite this URL action in the vuejs compatible format as I'm new to VueJs
The # symbol is razor syntax. In js frameworks you no longer have the # symbol. In the case of urls, you usually just use strings. Just use
<a href='/loanorigination/loanrequest'>APPLY NOW
Or for more flexibility, look up Vue Properties and pass it in to your component as a property called something like loanUrl and use {loanUrl} in place of the string above.

How do you prevent newline added to Handlebars partial?

Scenario: one-line Handlebars partial used in an inline element:
Handlebars template:
{{> partial}}Label
Partial:
<svg class="icon" viewBox="0 0 65 65"><use xlink:href="#icon"></use></svg>
Compilation result:
<a href="#section"><svg class="icon" viewBox="0 0 65 65"><use xlink:href="#icon"></use></svg>
Label</a>
As you see, partial comes across with the newline. There's no newline in the file.
It's on the handlebarsjs.com,
but not documented well enough (for me);
after a half an hour of struggling wandering where exactly am I supposed to set this "~"
{{#each arrayOfItems ~}}
<div>
{{~> item ~}}
</div>
{{~each}}
aaand, works like a charm for me:)
(handlebars-express3 on Node.js)
The issue was caused by the Vim's EOL management.
To prevent newline appearing after the Handlebars compilation, change Vim configuration (.vimrc) to include:
au BufWritePre * :set binary | set noeol
au BufWritePost * :set nobinary | set eol

Meteor #each block breaks #constant region

I have a D3 donut that tweens so i require that the svg be preserved. I find the #constant region works like a charm until i try and use a #each block around it to make more than one donut:
As simply as possible (donuts here returning single item)
{{#with donuts}}
<div id="donut-container-{{emoticonName}}" class="donut-container">
{{#constant}}
<img id="img-{{emoticonName}}" src="/images/emoticons/{{emoticonName}}.png" class="emoticon">
<svg id="svg-{{emoticonName}}" class="svg-donut"></svg>
{{/constant}}
</div>
{{/with}}
This works like a charm - tween behaves as svg is not re-rendered.
As soon as i do this however (donuts here returning [] with single item inside):
{{#each donuts}}
<div id="donut-container-{{emoticonName}}" class="donut-container">
{{#constant}}
<img id="img-{{emoticonName}}" src="/images/emoticons/{{emoticonName}}.png" class="emoticon">
<svg id="svg-{{emoticonName}}" class="svg-donut"></svg>
{{/constant}}
</div>
{{/each}}
The constant region no longer functions and things re-render instead of being preserved. Note in both cases here i'm still only rendering a single donut to isolate the issue to the #each block.
Any help with this would be appreciated.
Thanks.
So sometimes just the act of posing a question in a form clear enough for others to understand, makes the answer jump out...
{{#constant}}
{{#each donuts}}
<div id="donut-container-{{emoticonName}}" class="donut-container">
<img id="img-{{emoticonName}}" src="/images/emoticons/{{emoticonName}}.png" class="emoticon">
<svg id="svg-{{emoticonName}}" class="svg-donut"></svg>
</div>
{{/each}}
{{/constant}}
Seems so obvious i'm almost embarrassed :D
Try removing the constant tags and run meteor with meteor --release template-engine-preview-5.5. This will allow you to use reactivity while still working with D3. Once Meteor UI is released (probably along with Meteor 1.0 in early 2014) you can run the app with just meteor again.

Categories

Resources