When running feature Rspecs, I receive the following error (full trace at the bottom of this message)
Rack app error handling request {
The fact that the test passes just means that the test does not depend on that image being found. A broken image link will not generally cause a test to fail and it is in fact often the case that test writers do not even bother to supply mock images because it is (perceived to be) too much work and not relevant to the thing being tested.
See folks, this is why we ask for an example. Now that the OP has posted an example, we can see that his problem is browser caching, and will be solved by replacing
product.images.attach io: File.open(path), filename: 'image.png'
with
product.images.attach io: File.open(path), filename: "image-#{Time.now.strftime("%s%L")}.png"
in the helper that does the attachment. I would not have solved this without having the example.
ActiveStorage handles saving and serving files. OP was saving and serving images with it, which is definitely what it was intended for. In order to allow for different services to serve files in different ways, ActiveStorage separates the published URL from the actual image serving URL.
The published URL is almost a permalink: it is an encoded version of the database key for the attachment. ActiveStorage processes a request for the URL by looking up where the file is stored and sending a 302 temporary redirect to the URL that can be used to access the file, called a "service URL". When using AWS S3 to store files, the service URL can be a signed URL that expires quickly but nevertheless connects the browser directly to S3 rather than having to go through the web server as intermediary.
By default, the service URL is good for 5 minutes, and ActiveRecord explicitly sets
Cache-Control: max-age=300, private
on the 302 redirect. The browser caches this redirect response and for the next 5 minutes the browser will not even attempt to use or verify the published URL, it will immediately replace the public URL with the cached service URL.
Unfortunately, while the public URL is predictably recreated, the service URL is randomly generated, so when the browser does its automatic redirection, the previously valid service URL no longer works. The solution (or workaround, depending on your point of view) is to distinguish the public URLs by including a timestamp in the filename, so that tests will not reuse public URLs.
Sidenote
By the way, you should not be using url_for with image_tag. Change your ERB from
= image_tag url_for(product.image.variant(resize: "120x120"))
to
= image_tag(product.image.variant(resize: "120x120"))
Rails is smart enough to handle either case, but the latter way is the recommended way.
Something is likely off with how you're setting up the image that you're testing against. You might want to update that to how the Rails team handles it in their own tests:
module ActiveStorageHelpers
# ported from https://github.com/rails/rails/blob/5-2-stable/activestorage/test/test_helper.rb#L57
def create_file_blob(filename: "image.jpg", content_type: "image/jpeg", metadata: nil)
ActiveStorage::Blob.create_after_upload! io: file_fixture(filename).open, filename: filename, content_type: content_type, metadata: metadata
end
end
RSpec.configure do |config|
config.include ActiveStorageHelpers
end
Then place a tiny image file in spec/fixtures/file/images.jpg (that's where the file_fixture method will look for it).
With that in place, you can setup the image on your model in your feature test with something like:
instance_of_model.images.attach(create_file_blob)
I'm not sure what you mean with the exception happens after the test?
Test should be usually atomic and independent, so all resources you create should be removed immediately after your test finished. Also tests are running in random order, so tests which rely on each other will fail sometimes - and sometimes not, depending on the run order.
Can you share the output or tests which fail?