Faits :
A.
Les sociétés A._ Sàrl, jusqu'au 30 janvier 2020 B._ Sàrl, et C._ Sàrl sont l'une et l'autre actives dans le domaine des fournitures et des travaux de construction métallique.
C._ Sàrl s'est chargée d'exécuter des travaux sur divers chantiers pendant les années 2014, 2015 et 2016. Elle a sous-traité des travaux de pose de fenêtres à B._ Sàrl. Celle-ci a exécuté ces travaux avec la collaboration de D._, un ouvrier engagé et rémunéré par C._ Sàrl. Les deux entreprises ont régulièrement convenu du prix des travaux sous-traités, le plus souvent à forfait, et convenu que le prix serait réduit à raison de la collaboration de D._. Les modalités supposément convenues pour le calcul de cette réduction ne sont pas connues.
B._ Sàrl a établi le 30 novembre 2016 une facture n° 109/16 à l'intention de C._ Sàrl. Elle y faisait état de travaux exécutés sur plusieurs chantiers au prix total de 281'923 fr.20. Outre les acomptes reçus, elle portait en déduction 46'008 fr. (25'000 fr. et 21'008 fr.) pour des heures de travail accomplies par D._. Le solde réclamé s'élevait à 35'515 fr.20. C._ Sàrl a reconnu devoir 10'243 fr.20 qu'elle a aussitôt versés.
Le 30 novembre 2016 aussi, B._ Sàrl a établi une facture n° 110/16 au montant de 25'674 fr.60 pour d'autres travaux. C._ Sàrl a contesté toute obligation supplémentaire.
B.
Le 22 novembre 2017, B._ Sàrl a ouvert action contre C._ Sàrl devant le Tribunal civil de l'arrondissement de l'Est vaudois. La défenderesse devait être condamnée à payer 51'189 fr.60 avec intérêts au taux de 5% par an dès le 2 janvier 2017.
La défenderesse a conclu au rejet de l'action.
Le tribunal a tenu audience et recueilli des témoignages le 14 janvier 2019. L'un des témoins cités n'a pas comparu. La demanderesse a requis que ce témoin fût cité à nouveau. La défenderesse s'est opposée à cette requête, que le tribunal a rejetée.
Le tribunal s'est prononcé le 22 janvier 2019; il a rejeté l'action.
La Cour d'appel civile du Tribunal cantonal a statué le 9 juillet 2019 sur l'appel de la demanderesse. Les deux parties persistaient dans leurs conclusions de première instance. Accueillant partiellement l'appel et l'action, la Cour a condamné la défenderesse à payer 14'472 fr. avec intérêts au taux de 5% par an dès le 13 janvier 2017.
C.
Agissant par la voie du recours en matière civile, la demanderesse requiert le Tribunal fédéral, principalement, d'annuler l'arrêt de la Cour d'appel, de renvoyer la cause à cette autorité et de lui enjoindre d'entendre le témoin défaillant lors de l'audience du 14 janvier 2019, puis de rendre un nouvel arrêt. Subsidiairement, la demanderesse réclame que la défenderesse soit condamnée à payer 19'832 fr. avec suite d'intérêts.
La défenderesse n'a pas été invitée à répondre au recours.
D.
Agissant elle aussi par la voie du recours en matière civile, cette partie-ci requiert le Tribunal fédéral de rejeter entièrement l'action.
Invitée à répondre à ce recours, la demanderesse n'a pas procédé.
Par ordonnance du 17 octobre 2019 l'effet suspensif est conféré au recours.

Considérant en droit :
1.
Les deux recours étant dirigés contre la même décision, il y a lieu de joindre les causes et de statuer par un arrêt unique.
2.
Les conditions de recevabilité du recours en matière civile sont en principe satisfaites pour les deux recours, notamment à raison de la valeur litigieuse; celle-ci est déterminée par les conclusions articulées devant la Cour d'appel (<ref-law>).
3.
La demanderesse fait grief aux autorités précédentes d'avoir violé son droit d'être entendue en refusant de citer à nouveau le témoin défaillant lors de l'audience du 14 janvier 2019.
En vertu de l'art. 29 al. 2 Cst., tout plaideur a en principe droit à l'administration des preuves qu'il a valablement offertes. Le juge est néanmoins autorisé à effectuer une appréciation anticipée des preuves déjà disponibles et, s'il peut admettre de façon exempte d'arbitraire qu'une preuve supplémentaire offerte par une partie serait impropre à ébranler sa conviction, refuser d'administrer cette preuve (<ref-ruling> consid. 3.3 p. 64; <ref-ruling> consid. 5.3 p. 236/237; <ref-ruling> consid. 3 p. 157).
La Cour d'appel a ainsi apprécié par anticipation le témoignage que la demanderesse persistait à offrir. Elle a motivé son appréciation. A l'appui du recours en matière civile, la demanderesse se borne à proposer une appréciation différente, sans tenter de mettre en évidence un jugement éventuellement arbitraire, c'est-à-dire indiscutablement erroné (cf. <ref-ruling> consid. 2.3 p. 266; <ref-ruling> consid. 4.1.2 p. 62). Son argumentation n'est donc pas conforme aux exigences concernant la motivation des recours pour violation de droits fondamentaux (<ref-law>; <ref-ruling> consid. 1.4.1 p. 254; <ref-ruling> consid. 6 p. 397; voir aussi <ref-ruling> consid. 2.3 p. 266); le recours est par conséquent irrecevable sur ce point.
4.
A l'instar du Tribunal civil, la Cour d'appel n'alloue aucun montant pour les travaux énumérés dans le décompte que la demanderesse avait joint à sa facture n° 110/16. Selon la Cour, il incombait à la demanderesse d'apporter d'abord la preuve que les travaux ainsi énumérés étaient exécutés en sus de ceux pour lesquels un prix forfaitaire avait été convenu, et ensuite la preuve de la convention intervenue entre les parties pour la rémunération de ces travaux supplémentaires. Or, aucune de ces preuves n'était apportée.
La demanderesse prétend avoir au contraire apporté ces deux preuves pour des travaux exécutés sur un chantier dit... et avoir ainsi établi une créance de 5'360 fr. en sus de celle constatée par la Cour d'appel à hauteur de 14'472 francs. La demanderesse ne réclame pas l'estimation du prix prévue par l'<ref-law>, et elle ne prétend pas avoir allégué et prouvé la valeur de son travail et l'ampleur de ses dépenses; cette disposition n'est donc pas en cause.
La Cour d'appel a motivé son appréciation des preuves de manière globale mais néanmoins concluante, semble-t-il, pour l'ensemble des travaux visés par la facture n° 110/16. La demanderesse revient sur chacun des éléments ainsi discutés et elle expose pourquoi, à son avis, les deux preuves sont apportées pour ses travaux sur le chantier.... Là également, elle propose une appréciation simplement divergente de celle de la Cour, sans tenter véritablement, autrement que par d'insignifiantes protestations et dénégations, de mettre en évidence une erreur certaine dans le jugement d'appel. L'argumentation ne satisfait pas, ici, aux exigence de la jurisprudence relative à l'<ref-law> qui concerne le recours dirigé contre des constatations de fait de la juridiction cantonale (<ref-ruling> consid. 1.4.3 p. 254; voir aussi <ref-ruling> consid. 1.3.1 p. 253; <ref-ruling> consid. 2.3 p. 266). Le recours de la demanderesse est donc irrecevable sur ce point aussi.
5.
Les travaux visés par la facture n° 109/16 et le prix réclamé en contrepartie étaient incontestés déjà devant le Tribunal civil. Les paiements à imputer sur ce prix étaient également incontestés. La valeur du travail fourni par l'ouvrier D._ devait être elle aussi imputée. Selon le jugement de première instance, il incombait à la demanderesse de prouver la valeur de ce travail pour établir le solde du prix encore dû; elle n'a pas apporté cette preuve et l'action en paiement était pour ce motif entièrement rejetée.
La Cour d'appel juge cette approche contraire à l'<ref-law> qui concerne notamment la répartition du fardeau de la preuve dans le procès civil. Selon son arrêt, la prestation de l'ouvrier D._ et la convention passée à ce sujet, entre les parties, sont des faits destructeurs dont la preuve incombe à la défenderesse, par opposition aux faits générateurs dont la preuve incombe à la demanderesse. Parce que cette prestation et cette convention n'ont pas été prouvées, elles ne peuvent justifier aucune imputation sur le prix dû à la demanderesse. Néanmoins, la Cour impute la valeur que cette partie-ci a reconnue à hauteur de 46'008 fr. dans sa facture n° 109/16; elle parvient ainsi au solde de 14'472 fr. alloué à cette même partie.
Ce raisonnement consacre une saine application de l'<ref-law> et il mérite d'être confirmé. L'imputation de 46'008 fr. se justifie au regard de l'<ref-law> en tant que la facture contient une reconnaissance de dette afférente à la prestation de l'ouvrier D._. Il est donc sans importance, contrairement à l'argumentation de la défenderesse, que la pertinence de ce montant ne soit établie par aucune preuve. Le calcul du solde encore dû à la demanderesse est pour le surplus incontesté. Le recours de la défenderesse se révèle donc mal fondé, ce qui entraîne son rejet.
6.
Chaque partie doit assumer l'émolument judiciaire afférent à son recours. Aucune d'elles n'a répondu au recours de l'autre; il n'est en conséquence pas alloué de dépens.

Par ces motifs, le Tribunal fédéral prononce :
1.
Les causes sont jointes.
2.
Le recours de la demanderesse est irrecevable.
3.
Le recours de la défenderesse est rejeté.
4.
La demanderesse acquittera un émolument judiciaire de 1'000 francs.
5.
La défenderesse acquittera un émolument judiciaire de 1'000 francs.
6.
Il n'est pas alloué de dépens.
7.
Le présent arrêt est communiqué aux parties et au Tribunal cantonal du canton de Vaud.
Lausanne, le 31 mars 2020
Au nom de la Ire Cour de droit civil
du Tribunal fédéral suisse
La présidente : Kiss
Le greffier : Thélin