The current workind directory (CWD) of a process is inherited at the OS level from the previous process or it can be changed for the current process using chdir(2). The OS (here I mean "the kernel") of course will always resolve any symlink to determine the end result which must be a directory, not a symlink (to a directory). For example the previous system call (chdir(2)) can return the error ELOOP when there were too many symbolic links to resolve. So from the OS point of view, there can't be a CWD not being a directory for any process: the OS will always resolve it the the real path without any symlink anywhere.
Once the shell has done cd /tmp/test/bar, the CWD path was resolved by the OS into /tmp/test/foo. For example, on a Linux system, ls -l /proc/$$/cwd will show the link to the resolved path as seen by the kernel: /tmp/test/foo.
The fact that the shell still displays bar in its prompt is that because it remembers the cd command done before. The behaviour could depend on the shell kind. I'll assume bash here. So its built-in pwd (but not the external /bin/pwd command), the $PWD variable and their use in $PS1 will "lie" to the user about the current directory.
Any process, such as realpath, or /bin/pwd run from the shell will of course inherit the actual CWD, which is /tmp/test/foo. So that's not a bug in realpath, it will never have a specific information about bar.
One possible awkward way, as suggested by Kusalananda is to reuse somehow the $PWD variable and prepend it to realpath's argument only if its argument isn't absolute already.
Here's an example. I'm not sure there are not ways to abuse it. For example, while the function below would cope, the $PWD variable itself doesn't behave well in bash 4.4.12 (Debian 9) but works fine in bash 5.0.3 (Debian 10) if there's a linefeed character in the path. When there's a linefeed somewhere, to be useful, a -z option should also be added to realpath but I'm not going to reimplement the whole parsing of options in this simple example.
myrealpathnofollowsym () {
for p in "$@"; do
if ! printf '%s' "$p" | grep -q -- '^/'; then
realpath -se "$PWD/$p"
else
realpath -se "$p"
fi
done
}
realpath, when the given pathname is a filename, does apwd -P(equivalent) to get the current directory path. Prepending$PWD/would be a solution, but an awkward one.cd bar, it's already too late: the shell is now in/tmp/test/fooand nothing run from it will be able to know aboutbar. The only thing still knowing aboutbaris the shell itself (built-inpwdbut not/bin/pwd,$PWDand its output in$PS1). To tell it otherwise, try:ls -l /proc/$$/cwd./proc/$$/cwd?