I am not able to get the svg xlink:href work as a dynamic property in Nuxtjs(Vue). I am trying to use it like below
<svg class="icon phone-icon">
<use
v-bind="{ 'xlink:href': '../assets/sprite.svg#icon-download' }"
></use>
</svg>
How do I make it work?
Nuxt does not process any string value in any object to check if it is a link or not, Use require to find the public path of your SVG
<svg class="icon phone-icon">
<use
v-bind="{ 'xlink:href': require('../assets/sprite.svg') + '#icon-download' }"
></use>
</svg>
Also, take a look at SVG Sprite Module, this module creates a clean way to work with SVG icons
On NuxtJS 2 I had to do the following:
<svg class="icon">
<use v-bind="{ 'xlink:href': require('~/assets/sprite.svg') + '#icon-download' }"></use>
</svg>
without ~ it did not work.
Related
I have I think a small issue but I can't resolve it since more than 2 hours ...
I have a VueJs application and I'm trying to display an image that came from an API.
In my register.html I have that code :
<img :src="'./assets/' +nation.drapeau"/>
When I check the browser I see the correct path './assets/images/drapeaux/AFC/Australie.png' but nothing is displayed !!!! Why ? My path is not ok ?
What I'm doing wrong ?
This is the structure of my VueJs folder
If you use dynamic src, you have to use require. It is handled by webpack and it knows to put it in dist after build.
<template>
<div>STATIC IMAGE</div>
<img src="./assets/logo.png" />
<div>DYNAMIC IMAGE</div>
<!-- <img :src="'./assets/logo.png'" /> IT DOESN'T WORK-->
<img :src="require('./assets/logo.png')" /> <!-- IT WORKS-->
</template>
Demo:
https://codesandbox.io/s/dazzling-leftpad-i3stg?file=/src/App.vue:0-281
Another source:
How to import and use image in a Vue single file component?
Try using require since it's a dynamic src
<img :src=require(`./assets/${nation.drapeau}`)/>
The response , thanks guys :
<img :src="require('#/assets/' +nation.drapeau)"/>
I am able to locate elements other than svg using either JS Path OR by using the plugin created by sukgu (https://github.com/sukgu/shadow-automation-selenium)
The problem is with svg element present inside the Shadow root, I am not able to locate it.
Tried below methods:
While trying css selector to find the svg element, got below error:-
WebElement ele = (WebElement) js.executeScript("return document.querySelector(\"body > sn-component-va-web-client\").shadowRoot.querySelector(\"#Path\")"); ele.click();
Output -
org.openqa.selenium.ElementClickInterceptedException: element click
intercepted: Element
Using above mentioned plugin to find the svg - Using css selector
WebElement close = shadow.findElement("div > div.sn-cs-header > div.header-menu > div.menu-item.new-conversation-clicker > div.new-conversation-button > div > svg"); close.click();
Output -
org.openqa.selenium.ElementNotVisibleException: Element with CSS div >
div.sn-cs-header > div.header-menu >
div.menu-item.new-conversation-clicker > div.new-conversation-button >
div > svg is not present on screen
Using Xpath
WebElement close = shadow.findElementByXPath("//*[local-name()='svg']//g//g//g//path[#id='Path']"); close.click();
Output -
org.openqa.selenium.ElementNotVisibleException: Element with XPath
//*[local-name()='svg']//g//g//g//path[#id='Path'] is not present on
screen
Below is the HTML :-
<div class="conversation-container" style="display: block;">
<iframe title="Chat Support" id="myiFrame" class="chat-frame" scrolling="no" horizontalscrolling="no" verticalscrolling="no" frameborder="none" ng-src="/$sn-va-web-client-app.do?sysparm_nostack=true&sysparm_stack=no" src="/$sn-va-web-client-app.do?sysparm_nostack=true&sysparm_stack=no"></iframe>
</div>
<iframe title="Chat Support" id="myiFrame" class="chat-frame" scrolling="no" horizontalscrolling="no" verticalscrolling="no" frameborder="none" ng-src="/$sn-va-web-client-app.do?sysparm_nostack=true&sysparm_stack=no" src="/$sn-va-web-client-app.do?sysparm_nostack=true&sysparm_stack=no"></iframe>
#document
<html>
<head>
<body>
<sn-component-va-web-client component-id="cid1" now-id="cid1"></sn-component-va-web-client>
#shadow-root (open)
<div class="sn-cs-webclient fill-window text-direction-ltr">
<div class="sn-cs-accessibility-reader" aria-live="polite" aria-atomic="false"></div>
<div></div>
<div class="sn-cs-header" style="z-index: 500;">
<div class="chat-title">
<div class="header-circle">
<img class="header-icon " src="599c06dedbbe6c109005db184b961967.iix" alt="Header Icon">
</div>
</div>
<div class="header-menu">
<div class="menu-item new-conversation-clicker " aria-label="End conversation" aria-haspopup="menu" role="button" aria-describedby="new-conversation-tip" tabindex="0">
<div class="new-conversation-button">
<div class="new-convo-icon close-icon">
<svg viewBox="0 0 26 23" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<g id="Symbols" stroke="none" stroke-width="1" fill="rgba(0,0,0,0)" fill-rule="evenodd">
<g id="header/New-header-la-no-name" transform="translate(-330.000000, -20.000000)" fill-rule="nonzero" stroke="#ffffff" stroke-width="2">
<g id="Group" transform="translate(329.000000, 20.000000)">
<path d="M13.55,1 C7.17042969,1
<!-- removed extra numbers --> 19.9295703,1 13.55,1 Z" id="Path">
</path>
</g>
</g>
</g>
</svg>
Please try the following:
WebElement root = driver.findElement(By.cssSelector("body > sn-component-va-web-client"));
WebElement shadow_root = expand_shadow_element(root);
WebElement path = shadow_root.findElement(By.cssSelector("g > g > path"));
path.click();
public static WebElement expand_shadow_element(WebElement element)
{
WebElement shadow_root = (WebElement)((JavascriptExecutor)driver).executeScript("return arguments[0].shadowRoot", element);
return shadow_root;
}
Credits to the author
I suppose the problem is the different namespace the svg elements are in.
Take a look here : https://www.inflectra.com/support/knowledgebase/kb503.aspx
So probably you need (if the g-elements are irrelevant):
//*[local-name()='svg']//*[local-name()='path' and #id='Path']
If the g-elements are relevant, you need:
//*[local-name()='svg']/*[local-name()='g']/*[local-name()='g']/*[local-name()='g']/*[local-name()='path' and #id='Path']
Or maybe even use the XPath id-function like this:
id('Path')
I was able to locate/click on the svg element with a workaround, instead of finding xpath of svg element, I tried locating the element prior to svg.
Steps:-
Identify and click on the non-svg element prior to svg element
Shadow shadow = new Shadow(driver); // Using sukgu plugin
WebElement x = shadow.findElementByXPath("xpath");
x.click();
Move focus to the svg element using actions class and click on it
Actions action = new Actions(driver);
action.sendKeys(Keys.TAB).build().perform();
action.sendKeys(Keys.SPACE).build().perform();
Any answer would be a hit & trial without actually looking into the DOM.
ShadowDOM'S are often tricky.
In case you usually struggle around these areas, I suggest you install and use the Selectorshub extension for chrome: https://chrome.google.com/webstore/detail/selectorshub/ndgimibanhlabgdgjcpbbndiehljcpfh?hl=en
Once install check out this link to understand how to right paths for shadow dom:
https://www.youtube.com/watch?v=SCOAS86rJ9E
It has many other features which will make you write paths quickly. pretty good extension imo for ui-automation purpose.
How to add a link to an image properly using nuxt?
I am currently using tag="img" but it seems tag prop is deprecated. So is there a better way?
<nuxt-link
tag="img"
:src="require('~/assets/ProfitApp-icon.png')"
height="55"
alt="logo"
class="px-3"
to="/"
/>
WARN [vue-router] 's tag prop is deprecated and has
been removed in Vue Router 4. Use the v-slot API to remove this
warning:
https://next.router.vuejs.org/guide/migration/#removal-of-event-and-tag-props-in-router-link.
Why not using a slot like described here: Enclosing a router-link tag in an image in vuejs
<nuxt-link to="/" class="px-3">
<img
:src="require('~/assets/ProfitApp-icon.png')"
height="55"
alt="logo"
/>
</nuxt-link>
I have en issue with angular and font awesome. On first generation of list of icons suddenly all css class based icons are translated to svg. It affects only solid icons. for example :
<i class="fas fa-2x fa-minus-square"></i>
is translated somehow to
<svg _ngcontent-c16="" class="svg-inline--fa fa-minus-square fa-w-14 fa-2x"
ng-reflect-ng-class="fas fa-2x fa-minus-square" aria-hidden="true" data-prefix="fas" data-icon="minus-square"
role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg="">
<path fill="currentColor"
d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM92 296c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6 0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H92z">
</path>
</svg>
<!-- <i _ngcontent-c16="" class="fas fa-2x fa-minus-square" ng-reflect-ng-class="fas fa-2x fa-minus-square"></i> -->
Is there any option which can prevent this situation? Force somehow translation?
It can be problematic. For example I cannot use solid icons :(
If you'd like Font Awesome not to automatically replace <i> tags that look like icons with the corresponding <svg>s, you could change the configuration to disable autoReplaceSvg.
If you're loading via <script> tag, that might look like this (make sure to do the config before loading Font Awesome):
<head>
<script type="text/javascript">
// Notice how this gets configured before we load Font Awesome
window.FontAwesomeConfig = { autoReplaceSvg: false }
</script>
<script src="fontawesome.js"></script>
<script src="fa-solid.js"></script>
</head>
Or if you're building your own bundle and can access the config from within your own script you could do this:
import fontawesome from '#fortawesome/fontawesome'
fontawesome.config = { autoReplaceSvg: false }
I had the same issue, the icon tag was actually translated to SVG when I inspected the element.
The problem was I was loading fontawesome both via CSS and JS calls. When I removed the call to the JS lib and only called the CSS file, the icons rendered properly.
I am using vuetify and would like to add an SVG icon to the start of the text field. I know you can prepend or append icons from v-icon, but I would like to use my own SVG image in a similar way.
Just use the "prepend" slot:
<v-text-field label="My text field" type="text">
<template v-slot:prepend>
<img width="24" height="24" src="[PathToAssets]/whatever.svg" >
</template>
</v-text-field>
You can read about the public path
I would strongly recommend using the public path:
Add your svg image to public/img/icons/test.svg.
Use the img tag like this <img src="/img/icons/test.svg"> to point to the svg location.
If you really dont want to use the public path for your svg's you can use this loader to import your svg's: https://github.com/visualfanatic/vue-svg-loader