Time is necessary to master any tecnology, frustration is part of the process. I have struggled with this same problem a while ago. Here is a snippet you can copy and paste in google chrome developer console to see it working. The web appbuilder application must be opened in the browser tab for you to try this.
I think this part of the api is really missing some docs. LayerStructure module uses LayerInfos behind the scenes. The sample code uses LayerInfos module directly.
var LayerInfos = require('jimu/LayerInfos/LayerInfos');
var InfoTemplate = require('esri/InfoTemplate');
function getWebmapOperationalLayerById (layerId) {
var instance = LayerInfos.getInstanceSync();
var layerFound = null;
instance.traversalLayerInfosOfWebmap(function (aLayer) {
if (aLayer.id === layerId) {
layerFound = aLayer;
return; //get out of traversalLayerInfosOfWebmap()
}
});
return layerFound;
}
function modifyInfoTemplate( layerObject) {
var title = 'Popup title';
var content = 'Custom description. You can use HTML here. <br> And access attribute value like this ${SOME_ATRIBUTE}';
layerObject.infoTemplate = new InfoTemplate(title, content);
}
var layerId = 'YOUR_LAYER_ID_HERE';
var operationalLayer = getWebmapOperationalLayerById(layerId);
operationalLayer.getLayerObject().then(modifyInfoTemplate);
It is important to use operationalLayer.getLayerObject() method (instead of accessing directly operationalLayer.layerObject), because sometimes layerObject is not loaded and will be empty. getLayerObject() will assure the object is loaded before you modify infotemplate.
To find a layerId you can use _viewerMap._layers in chrome developer console to see what's in there.