Drawing on Cadasta world map with Leaflet JS Library within a Selenium Test
While I’m implementing Selenium UI tests for Projects entity the biggest challenge I faced was to find a way to draw things on Cadasta world map.
Cadasta uses django-leaflet to include maps in it. As usually I asked for the help in cadasta.slack.com. Both Kate and Oliver guided me on this to interact with Leaflet JavaScript API to draw things on map. In order to execute JavaScript within python Selenium we have to use WebDriver.execute_script().
Here is what we should execute inside execute_script().
In order to interact with map first we need to get a reference to the map object. But it is not straight forward. As per [1], django-leaflet does not store the map object in global scope, so we have to make it store the map object in global scope by changing the LEAFLET_CONFIG[‘NO_GLOBALS’] = False in settings.
Then we can access the map object by window.maps[0].
'map = window.maps[0];'
Next step is to draw on the map. Here is how to draw a simple polygon.
'var polygon = L.polygon([' +
' [56.51, 20.047],' +
' [51.509, 10.08],' +
' [53.503, -0.06],' +
' [58.51, 0.047]' +
']).addTo(map);'
Now we’re done with JavaScript.
Here is the complete code for python selenium test case to draw a polygon on map.
script = (
'map = window.maps[0];'+
'var polygon = L.polygon([' +
' [56.51, 20.047],' +
' [51.509, 10.08],' +
' [53.503, -0.06],' +
' [58.51, 0.047]' +
']).addTo(map);'
)
self.wd.execute_script(script)
But since we are trying to execute the script within a selenium test case this is not enough, because the window.maps might not be loaded at the time of test case being running.
So before executing the above code lines we should check the page state [2]. Here is how to do it.
page_state = self.driver.execute_script('return document.readyState;')
We have to wait for the document.readyState becomes complete. For that I used below python loop[3].
page_state = self.wd.execute_script('return document.readyState;')
while page_state != 'complete':
page_state = self.wd.execute_script('return document.readyState;')
print page_state
print page_state
Now we are done with drawing on map!
References
[2] http://stackoverflow.com/questions/26566799/selenium-python-how-to-wait-until-the-page-is-loaded
[3] https://wiki.python.org/moin/ForLoop
[3] https://docs.djangoproject.com/en/1.10/topics/settings/
[4] https://docs.djangoproject.com/en/1.10/intro/tutorial01/
[5] https://docs.djangoproject.com/en/1.10/topics/settings/
[6] http://leafletjs.com/examples/quick-start/
[7]https://www.mapbox.com/mapbox.js/example/v1.0.0/leaflet-draw/