As others already said, if you are unhappy with their output, then please talk to them about their output. If you expect a better output for the money you pay, by all means say so and act accordingly.
However:
They are not communicating that they are blocked on their tasks so I consider this stealing from the client and myself.
While you have bought their time, programming isn't a job where you can hack at a keyboard for 8 straight hours. You will always have phases (and the more often the more senior you get) where you have to wait for something. This very answer here is for example brought to you courtesy to a typescript open api generator bug that I fixed... and now I have to wait 15 minutes for all tests to pass. Has my employer bought my time and are they entitled to order me to just stare at the slowly moving progress bar on my screen and not post here? Yes they are. But insisting I do so would not make their task go any faster.
In the office, I would use this time to get up, stretch my legs, use the restroom, maybe clean the coffee machine or fill the community kitchen dishwasher. Not exactly the tasks in my working contract and certainly not bringing our app closer to completion. Since those tasks are not something you can repeat as often as you like (at some point the coffee machine is clean enough), I do answer questions on Stack Overflow. Because I have to wait.
Now you could ask "But there is so much more work to do, why do you wait, just take the next ticket!". Well, yes. That is fine when tickets are no-brainers. But they aren't. You have to load up all the knowledge required and that means "unloading" all the previous knowledge from the ticket in waiting, because brain capacity is limited. I work for you so I filled my brain to the hilt with everything I need to do the task I have, there is no extra room I held back.
In actual hardware that is called "setup times" according to my dictionary. The time a machine takes to be setup to do something else. If you have a machine furbicating widget A and you can set it up to instead fobicrate widget B, then you can do something else with the machine if you don't need widget A furbicated. Lets say between 11:00 and 12:00 the foreman for furbicating is on their break, you could set up the machine to fobricate widget B in that hour. But setting up the machine does not come free. It takes time. If it takes 45 minutes to change it to widget B and then 45 minutes to change it back, your order of widget A will be delayed if you actually do so. Just because you can does not mean it's a good idea.
The same goes for knowledge workers. Imagine the brain to be a memory space, you can upload all the context for task A. And then you have to wait 20 minutes. Uploading context for B might take 15 minutes, but it will delete the context for A. Now... you could do B while you wait, but then you will need another 15 minutes to drop B and upload context for task A again. Which is a net loss. Do it once and task A will be late, do it multiple times a day and you will have performance problems because all you do is context switching instead of staying in one and working.
For me, cleaning the coffee machine, answering Stack Overflow questions or stretching my legs all keep the context of what I did before. They aren't super challenging. Starting a new piece of work will lose the context and I have to aquire it again, costing time.
As an employer you do have the right to frustrate me by ordering me to watch the progress bar instead of posting here. But again... the task does not finish one second sooner if I actively watch it.
So... your focus should be on whether that developer reaches the goals you agreed on. Quite frankly, whether they slave away 8 hours typing franticly on their keyboard or whether they meditate 6 hours and then slowly type their perfect solution or whether they are on hackerrank should not concern you.
Do they get their work done, or not?