First, that alleged "extra cost" is the #1 myth. It might be true of test-last (code then test, anti-TDD; whatever it's called)-- I am not sure because I've never tested that way and that process is transparently ineffective if you take a very structured approach to the process (more later). I've been at a place where I also believed the same thing but since then I've built larger and larger systems and felt these pains. While TDD will slow you down initially as you learn, once you're comfortable with your testing framework, you'll notice you don't really go slower because you have near zero debug time, feel absolutely empowered to refactor and clean code, clarify intentions and just generally make everything crystal clear without breaking anything. You'll also notice that in most cases, as projects grow large and cumbersome, you keep that same steady methodical pace

Second, TDD is not E2E testing. There are tools for E2E but when we're talking about refactoring or structural organization it isn't so much a matter of UIs as it is a matter of what happens within the logical decisions of the system, which hopefully is not contained within the UI for non-UI logic. The description of your problem does not sound like you have an issue with the website's frontend but with the complexity of its brains behind the scene.

So you'll want some tests to cover the application code units individually (unit tests), and something which makes sure you can glue all of those pieces together and they still work as expected (integration tests). An integration test is not end-to-end, it's simply multiple components. Each of those components should already have passing tests, so you should have very high confidence that they work in isolation. The integration test simply makes sure they're connected the right way. I prefer as few integration tests as possible (but at least 1). If you have lots of integration tests you're probably performing at least some testing which should be covered by unit tests within those integration tests. Integration tests should just make sure the components are compatible and connected, not really test their internal behaviors.

I personally do the highest level of finalized testing (V&V) manually because I've proven the components work and are wired correctly, so the UI is usually just a dumb wrapper dumping out HTML. I open a browser and click around, make sure it works, think about how I can break it, beat it up for a few minutes and appreciate my work. You could automate this part of the process but I haven't found sufficient reason to (yet).

TDD is simply writing an assertion and then satisfying it with code. At the end, you've independently computed and verified that some tiny granule of code has some certain behavior.

When I started I'd think to myself "ok, I'm going to write the sorting code" and then I'd run off writing tests to make sure some simple structure was sorted after being passed through the method. That's way too fast. The best way I've heard the proper approach described is when Bob Martin says "test the most degenerate case first".

So my sorting would start off with sorting null. What should happen if that unit gets null instead of the expected array? What does it return? Does it throw an Exception?

Refactor time. Why does the code suck? How would it be easier to understand? Any methods too long? Any repetition? Don't add tests, don't change behavior. Only change the way the result is reached.

Test subsequent cases like null/false/zero/undefined. Refactor after each, if appropriate. Don't skip refactoring! You don't always have to do it but you should consider whether or not it is currently appropriate.

After those cases you can test the simplest things; an empty array. It should probably return an empty array. Then refactor. Then a single-element array, refactor, then two... then three, then the three in various orders.

At a certain point you can't write a test that fails. You're done with this unit of code. Everything provably works. I realize all of this seems like an overengineering process that's too low-level to be remotely sane. Seriously, I understand why you might think that. The thing is, all code is written one line at a time. Every second spent on the tests is paid for by the absence of debugging, dumping variables to screen, viewing source, etc. I'd argue that time spent debugging is time least effectively spent, particularly when in vein.

BTW money isn't my primary motivator either, I just enjoy programming. Make the best of it; do what you enjoy and get paid for doing it but don't look at the money as a carrot. If you can't stay motivated then maybe it isn't a matter of career but a matter of the project or industry?