perliedman / leaflet-routing-machine

Control for routing in Leaflet
https://www.liedman.net/leaflet-routing-machine/
Other
1.06k stars 347 forks source link

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

Closed LLStudent83 closed 1 year ago

LLStudent83 commented 1 year ago

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(); });

LLStudent83 commented 1 year ago

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???

curtisy1 commented 1 year ago

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

LLStudent83 commented 1 year ago

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?

curtisy1 commented 1 year ago

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 
```js
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

LLStudent83 commented 1 year ago

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.

LLStudent83 commented 1 year ago

The problem is solved. See the post above.