perliedman/leaflet-routing-machine

Passing the icon option: New icon(<...>) in L.marker leads to jest test error

LLStudent83 opened this issue · 6 comments

Good afternoon. I really need your help. There is a project to draw a route on the map. The route is built using class RoutingMachine extends MapLayer. The construction of route points is implemented through the createMarker method of the L.Routing.Plan interface. There was a problem with testing this component.
With this code, the component is rendered in a test environment:
createMarker: (i, start, n) => {
some kind of code
const marker = L.marker(start.latLng, {
// icon: new Icon({
// iconUrl: home // home is SVG picture
// iconSize: [45, 45],
// })

return marker;
},

With this code, the component is not rendered in a test environment:
createMarker: (i, start, n) => {
some kind of code
const marker = L.marker(start.latLng, {
icon: new Icon({
iconUrl: home // home is SVG picture
iconSize: [45, 45],
})

return marker;
},

just throws an error :
TypeError: symbol is not a function
at String ()

  at Object.exports.DOMString (node_modules/react-scripts/node_modules/webidl-conversions/lib/index.js:283:12)
  at Object.exports.USVString (node_modules/react-scripts/node_modules/webidl-conversions/lib/index.js:299:23)
  at HTMLImageElement.set src [as src] (node_modules/react-scripts/node_modules/jsdom/lib/jsdom/living/generated/HTMLImageElement.js:174:35)
  at NewClass._createImg (node_modules/leaflet/src/layer/marker/Icon.js:141:9)
  at NewClass._createIcon (node_modules/leaflet/src/layer/marker/Icon.js:108:18)
  at NewClass.createIcon (node_modules/leaflet/src/layer/marker/Icon.js:89:15)
  at NewClass._initIcon (node_modules/leaflet/src/layer/marker/Marker.js:205:27)
  at NewClass._initIcon (node_modules/leaflet-rotatedmarker/leaflet.rotatedMarker.js:23:28)
  at NewClass.onAdd (node_modules/leaflet/src/layer/marker/Marker.js:112:8)

test code
it('map rendered', () => {
const initialState = {
mapSearch: {
zoom: 5,
},
};
const store = createStore(reducers, initialState);
const mapLayout = (
<Provider store={store}>
<MapLayout directionsInfo={directionsInfo} mapUpdate={false} />
</Provider>
);

render(mapLayout);

screen.logTestingPlaygroundURL();

// expect(screen.getByLabelText('Направление')).toBeInTheDocument();
});

The experiment showed that if an image in PNG format is transferred to the place of the SVG image in iconUrl, the test ends positively. What could be the problem???

This is certainly weird, but given the stacktrace, I expect it to be a bug in the jsdom. I'm not very familiar with how it works but I know jest uses it (and the test case looks very much like jest).

I know for a fact that SVG markers do work with a standard browser, so it's not on the leaflet or lrm side of things.

Can you show me the svg and how you import it into your code? That would be helpful in getting a reproducable for the jsdom folks to examine

Good afternoon. Thank you so much for your prompt response.
Here is my SVG:
<svg id="Слой_1" data-name="Слой 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 74.78">
<defs>
<style>
.cls-1{fill:#000;stroke:#eee;stroke-miterlimit:10;stroke-width:2px;fill-rule:evenodd;}
</style>
</defs>
<path
class="cls-1"
d="M930.35,534v41h20V547h20v28h20V534l-30-29Z"
transform="translate(-928.35 -502.22)"
/>
</svg>
SVG are imported into the code like this
// import house from '../../../../static/icons/house.svg';
Have I answered your questions correctly?

SVG are imported into the code like this
Oh, I'm not sure if that can work properly. I believe L.Icon is used solely for loading remote images from a cdn or server.
So, instead of doing

import house from '../../../../static/icons/house.svg'

const marker = L.marker(start.latLng, {
icon: new Icon({
iconUrl: home, // home is SVG picture
iconSize: [45, 45],
})
})

try doing

const marker = L.marker(start.latLng, {
icon: new Icon({
iconUrl: '../../../../static/icons/house.svg', // home is SVG picture
iconSize: [45, 45],
})
})

this way, Leaflet will take care of the image loading for you.

Alternatively, if this doesn't do the trick, you could use L.DivIcon instead and pass the imported svg as html probably

Hi Alex. Option one turned out to be non-working. The variant with L.DivIcon worked. But the team leader did not allow it. I solved the problem on my own. I installed @testing-library/jest-dom" and eslint-plugin-jest-dom. But I'm still very grateful to you for your help.

The problem is solved. See the post above.