The issue might also lie in a too rigid separation of task between back-end and front-end development.
If a front-end developer need a new API, isn't it possible to allow him or her to create a dummy API on the back end (returning always the same value for example) to validate the layout ? Then commit that partial implementation with a stub, and in a second time, a back-end developer will implement the real feature.
By breaking the dependency, you will get a better flow and you don't have stop everything waiting for a single task that acts as a bottleneck.
In Gitflow Workflow, an hotfix is a branch that is created from master and in the end is merged back in master AND in develop.
The general (and well known) idea behind the "don't directly commit on master", is to have in master, a state of your code that is completely safe to deploy in production.
However, it can serves other means. For Github, the master also serves as a tracking tool to know when a feature is put in production. If you commit on another branch and then fast-forward master on it, you will lose the merge commit, and by extension, you'll just put a lot of tiny commits in your master timeline, losing the ability to revert a whole feature by simply revert the previous merge.
Another problem with this approach, is to know WHEN you can release/deploy. If everyone commit on master, you will have to synchronize all the development to have a coherent state of your code. For monolithic releases with a clear scope, it can be ok, but in my case, as an integration developer, features come and go and you have never a single point in time when "all features are done".
However, not commit in master does not mean having a branch master and a develop. As pointed in the Github presentation, if you do a feature branch workflow, you can work only with a master, creating a branch for each feature, and merges them back in master (without fast-forward) at the end.
In my humble opinion, Git Flow (master/develop + features/hotfix/release branches) is more adapted in a context where you don't really know when you'll have to release it (not at each feature done), and when the last release is often the one to hotfix. A gitflow chart can be convoluted, while a feature branching workflow is often more simple to read. The "noise" is often due to release/hotfix commit in what will be deleted branch some minutes after.
Example for Gitflow
Example of graph for Feature Branching Workflow
Best Answer
QA should probably be testing twice.
The first testing should be around the specific changes and done on the feature branch. This lets QA test around the specific changes and see that the particular change is complete as specified and behaves as expected. It also gives them an early preview for the second round of testing, which is what actually matters for QA.
Coming from my background in various regulated environments, the second testing needs to be done on either a tag on the development branch that corresponds to a release, or the release branch, or perhaps the master branch. Prior to a release, QA should be testing the full and complete code that is going to be deployed prior to it being deployed and you should be able to assert that whatever was tested by QA is exactly identical to what gets deployed to production. My preference would be that after a code freeze, a tag is applied to the release branch and QA would test that. Changes would be done in a develop branch, spot checked, and then tested again in a new tag on the release branch. These tags on the release branch would correspond to release candidates. An approved release candidate would be merged into master and then identified as the released version.
I am making a few assumptions here. First, you have somewhat decent developer-based test coverage. Ideally, this would be automated unit and integration tests that developers run and do so before sending any code on any branch to QA. Developers may also want to do some exploratory testing around the UI to make sure that things look right before QA testing. Second, there is good coordination between development and QA to plan the changes being incorporated to ensure sufficient QA time based on features.