Run job based on previous job results

I essentially want to only run my end to end test job if I have at least one of my two jobs (backend and front) have passed and there isn’t a failure. I am struggling to figure out the syntax. This is what I currently have:

    name: Cypress Tests
    runs-on: ubuntu-latest
    needs: [ backend, frontend, changes ]
    if: |
      (needs.backend.result == 'success' && needs.frontend.result == 'success') ||
      (needs.backend.result == 'success' && needs.frontend.result == 'skipped') ||
      (needs.frontend.result == 'success' && needs.backend.result == 'skipped')

For whatever reason, it skipped this job when my backend job was successful and my frontend was skipped. As per the screenshot below. Is there an easy way to do this? I have tried !failed() but then if both backend/frontend jobs are skipped (which is a viable flow) it will trigger the job. I need to run the job if either of backend/frontend is success and the other job isn’t failed.

For what it’s worth, I get it to work with the below, although to be honest I’m struggling to wrap my head around why my initial expression didn’t work:

    if: |
      always() &&
      !(needs.frontend.result == 'failure' || needs.backend.result == 'failure') &&
      !(needs.frontend.result == 'skipped' && needs.backend.result == 'skipped')

With the above way, I find that you can’t manually cancel workflows anymore (I’m guessing due to the always()). Is there a way that I can specify the if expression to meet my conditions but will also allow me to manually cancel the job once it has started?