Recently at Postman we decided to build “In-app Lessons” to provide our users with an unique on-boarding experience. The objective of the lessons is to skill up our users on different features inside Postman.

One of the major part of building this on-boarding system was to have the capability to reference parts of UI so that we can attach popovers while running a lesson.

But the problem here is that these lessons exists separately on a service and Postman app just fetches the required lesson and run it. So we needed to create a way that this service can reliably use to create lesson steps (popovers that are attached to an UI element).

We couldn’t use traditional query selectors or xpaths because they are tightly coupled with the DOM and the way how components are structured. Also there is always this risk that some attributes or elements could be removed during refactoring or implementing new features.

After some brainstorming and POCs we built our own flavour of XPATHS by leveraging React and its context API.

The idea here is to wrap all the components that you want to make referenceable with XPATH Component. What this enabled us to do is create a skeleton structure of our entire app which can be referenced and also allowed developers enough flexibility to build new features without worrying about removing or changing these XPATHs.

<XPATH identifier='app'> //...



<XPATH identifier='sidebar'>



//... </XPATH>

<XPATH identifier='main'>



//... <XPATH identifier='requestSection'>



//... </XPATH>

</XPATH>

</XPATH>

So from above you can see that now we have 4 sections that we can reference and also now developers can add/remove any code that they want without touching these XPATHS. Lets say a lesson step needs to show popover on “requestSection”. The way to reference it is app/main/requestSection.

We used context from React to provide parent’s path to its children. The XPATH components down in the React tree just compose on top of the paths provided by the parent and then again pass down this composed path. Now whenever an XPATH component is mounted, it registers the DOM node it is wrapping against its final path. Below I have added a codesandbox which shows a trimmed down version of the XPATH that we implemented inside Postman.