GSoC 2021 at Public Lab 🎈: Final Report

Mohammad Warid
6 min readAug 23, 2021

--

GSoC at Public Lab

If the experience could be summarised in one word that would be “memorable” ❤️.

About the project — spectral-workbench.js JS/Rails integration

The parent rails app, spectral workbench (SW) at https://spectralworkbench.org needed a new capture interface that could utilise the newly updated spectral workbench JS library (SW.js) from https://www.npmjs.com/package/spectral-workbench.

For starters, Spectral Workbench is a web app used to analyse and record spectral data by amateurs and researchers alike after which the captured data is contributed to a live open sourced database comprising of thousands of spectrums so that everyone can benefit it from. Check it out at here!

Project Implementation

Getting the dependencies right 🐤

So the first task in the project was to actually install the dependencies to their latest compatible versions since we deprecated bower in favour of yarn.

At the same time, there were outages on CDN, so we settled upon packages and gems which enabled the app to be non dependant over such links.

Even if a small dependency was updated, the app would break. So this involved some trial and error until all the dependencies were updated to their compatible versions #671

Things don’t always go as they are planned 😅

The sample interface implementation at https://publiclab.github.io/spectral-workbench.js/examples/new-capture/ utilised bootstrap stepper styles to switch to different functionalities.

When trying to port that functionality to the new implementation however, there was a major blocker that the capture interface wasn’t working on safari browsers on iOS and MacOS but was working perfectly on Firefox and Chrome #665.

No hate whatsoever with Safari but the issue was still frustrating
No hate whatsoever with Safari but the issue was still frustrating

We tried different approaches and later found out that the graphing library was the culprit since it required a specific height on a webpage to function. This could be due to the fact that different browsers used different JS engines under the hood, for instance Chrome uses the familiar v8 engine whereas Safari uses LLVM JIT.

The solution then was to use JS to handle the elements on the webpage instead of the bootstrap stepper styles.

So after creating a new route at /capture/v2, the work finally started to take some shape #660 🎉.

The major thing to consider throughout the project was that no current functionality must be hindered and all of the changes must be separate from the live working version at /capture.

Since the SW.js lib used the modern ES6 JS syntax, there were some asset pre-compilation issues with the uglifier gem which couldn’t recognise the new syntax. Once that was passed the app was successfully running again 🚀.

After this, we could take some component insights from the old interface like the login nav bar, login model, save spectrum partial and integrate into the new interface.

Next up, it was the time to style the app. Since the users would be using different devices and that too in different orientations, making the app responsive was essential, keeping in mind to hide distracting things like tooltip on button clicks. We were also utilising the already existing styles from the SW.js lib thereby following the DRY principle 🙌

Something to note here, most people think that the responsive devices pane on the chrome developer tools that they test the webpage on, would ultimately reflect the official results on the actual devices themseleves. Well, it’s not that simple. The different devices just simulate different screen sizes instead of actual devices. That’s because when I opened the same webpage on a device simulator, there I saw the CSS breaking which was supposed to be working fine since that’s what I had assumed from the Chrome dev tools 😂.

Don’t trust the responsive devices feature of Chrome dev tools

In order to restore the already existing functionality into the new app, like saving the spectrum to the upstream rails app and selecting a suitable calibration spectrum to better align the RGB peaks, there was a need of a new rails action under the capture controller #694. Also added basic tests to confirm the new route.

Multiple camera support 📷

The next thing to work upon was to add support for different video camera devices in order to switch between them at the time of capturing the spectrum. With the rising trend of multiple cameras on smartphones 🤳🏽 these days, it’s better to give users the option to switch between them as per their needs instead a choosing a default camera for example.

Camera source selection for video feed
Camera source selection for video feed

The approach for this was to get all the available media devices with type video in a dropdown list and when the user selects a different device, stop the current video stream and start the new stream with the selected device. This change was done in SW.js #247

Small enhancements

With the app finally in place we could then look at adding some enhancements like protecting pages having unsaved content with onbeforeunload events, which generates a confirmation prompt before reloading or leaving the webpage so there is less accidental data loss.

Sample prompt before quitting or refreshing the webpage
Sample prompt before quitting or refreshing the webpage

This was followed by making the interface more accessible in accordance with WCAG standards, by using appropriate aria labels and tags on different elements of the webpage #701.

Before and after of the accessibility performance on the new interface
Before and after of the accessibility performance on the new interface

Testing 👨🏻‍🔬🧪

Finally it was time for some system tests to make sure everything works as intended.

The problem here was the app didn’t have a native login unlike plots2, which meant there was the need for some user data which we could login into. There I came to know about the faker gem, which produces some fake user data to utilise in the app. We also needed to store the login session ids which would enable the user to login the tests. This was accomplished with the help of rack_session_access gem. The combined use of these gems produced random users with random names, emails and session ids which logged in the user into the app #702.

Once the login part was out of the way, we could then test the functional components with the help of Capybara and Selenium WebDriver. Since the app expected camera access, we tried to use the WebRTC recommended way of using fake video stream by passing in arguments to the Selenium Webdriver: — use-fake-ui-for-media-stream — use-fake-device-for-media-stream — use-file-for-fake-video-capture, but were unsuccessful. So more investigation is going on here .

All in all this project required a lot of patience to see the final result which is finally live here 🥳.

This GSoC experience not only helped me learn a new backend framework but more importantly it taught me the iterative cycle of software engineering in general, where there are breaking changes and things don’t always go as planned, feedback in the form of code reviews, alternative solutions to a problem with their pros and cons, stable and unstable versions, testing an implementation etc. I am truly grateful for Public Lab mentors to show their utmost guidance support and don’t plan on leaving the org anytime soon ✌🏻.

--

--