Problem polega na tym, że domyślnie kod JS jest synchroniczny, więc żeby dostać się do asynchronicznie dodawanego importu, musiałbyś opóźnić wykonywanie kodu w test.js. W przypadku ESM będzie to możliwe przy pomocy tzw. top-level await.
Niemniej proponuję o wiele lepszy i prostszy sposób: w app.js po prostu zwróć funkcję, która będzie wczytywać to API i przekazywać do callbacku, a w test.js opakuj wszystko w tę funkcję:
// app.js
module.exports = function getAPI( callback ) {
api.login( 'whatever', callback );
};
// test.js
const getAPI = require( './app.js' );
getAPI( function( api ) {
api.sendMessage( 'Witam' );
} );