diff --git a/.gitignore b/.gitignore
index ce917dd756..10dd2b4a9b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,7 @@ packages/driver/test/cypress/videos
packages/server/.cy
packages/server/.projects
packages/server/support
+packages/server/test/support/fixtures/server/imgs
packages/server/test/support/fixtures/server/libs
# CLI tool
diff --git a/packages/server/__snapshots__/2_form_submissions_spec.coffee.js b/packages/server/__snapshots__/2_form_submissions_spec.coffee.js
index 541c285709..a7d21c781f 100644
--- a/packages/server/__snapshots__/2_form_submissions_spec.coffee.js
+++ b/packages/server/__snapshots__/2_form_submissions_spec.coffee.js
@@ -1,4 +1,4 @@
-exports['e2e form submissions passing 1'] = `
+exports['e2e forms
+
+
+ """
+
+onServer = (app) ->
+ app.post "/verify-attachment", (req, res) ->
+ form = new multiparty.Form()
+
+ form.parse req, (err, fields, files) ->
+ fixturePath = path.resolve(e2ePath, "cypress", "fixtures", fields["foo"][0])
+ filePath = files["bar"][0].path
+
+ Promise.props({
+ fixture: fs.readFileAsync(fixturePath),
+ upload: fs.readFileAsync(filePath)
+ })
+ .then ({ fixture, upload }) ->
+ ret = fixture.compare(upload)
+
+ if ret is 0
+ return res.send('files match')
+
+ res.send(
+ """
+ file did not match. file at #{fixturePath} did not match #{filePath}.
+
+
+ buffer compare yielded: #{ret}
+ """
+ )
+
+ ## all routes below this point will have bodies parsed
+ app.use(bodyParser.text({
+ type: '*/*' ## parse any content-type
+ }))
+
+ app.get "/", (req, res) ->
+ res
+ .type('html')
+ .send(getFormHtml('action="/dump-body"'))
+
+ app.get "/multipart-form-data", (req, res) ->
+ res
+ .type('html')
+ .send(getFormHtml('action="/dump-body" enctype="multipart/form-data"'))
+
+ app.get "/multipart-with-attachment", (req, res) ->
+ res
+ .type('html')
+ .send(getFormHtml('action="/verify-attachment" enctype="multipart/form-data"', req.query.fixturePath))
+
+ app.post "/dump-body", (req, res) ->
+ res
+ .type('html')
+ .send(req.body)
+
+describe "e2e forms", ->
+ context "submissions with jquery XHR POST", ->
+ e2e.setup()
+
+ it "passing", ->
+ e2e.exec(@, {
+ spec: "form_submission_passing_spec.coffee"
+ snapshot: true
+ expectedExitCode: 0
+ })
+
+ it "failing", ->
+ e2e.exec(@, {
+ spec: "form_submission_failing_spec.coffee"
+ snapshot: true
+ expectedExitCode: 1
+ })
+
+ context "")
+ res.send(
+ """
+
+
+
+
+
+ """
+ )
printBodyThirdTime: (req, res) ->
console.log(req.body)
res.type('html')
- if counts[req.url] == 3
+
+ if counts[req.url] is 3
return res.send(JSON.stringify(req.body))
req.socket.destroy()
diff --git a/packages/server/test/support/fixtures/projects/e2e/cypress/fixtures/bigger-sample.pdf b/packages/server/test/support/fixtures/projects/e2e/cypress/fixtures/bigger-sample.pdf
new file mode 100644
index 0000000000..b7f1de7f22
Binary files /dev/null and b/packages/server/test/support/fixtures/projects/e2e/cypress/fixtures/bigger-sample.pdf differ
diff --git a/packages/server/test/support/fixtures/projects/e2e/cypress/fixtures/sample.jpg b/packages/server/test/support/fixtures/projects/e2e/cypress/fixtures/sample.jpg
new file mode 100644
index 0000000000..f77abf0a77
Binary files /dev/null and b/packages/server/test/support/fixtures/projects/e2e/cypress/fixtures/sample.jpg differ
diff --git a/packages/server/test/support/fixtures/projects/e2e/cypress/fixtures/sample.pdf b/packages/server/test/support/fixtures/projects/e2e/cypress/fixtures/sample.pdf
new file mode 100644
index 0000000000..f698ff53d4
Binary files /dev/null and b/packages/server/test/support/fixtures/projects/e2e/cypress/fixtures/sample.pdf differ
diff --git a/packages/server/test/support/fixtures/projects/e2e/cypress/integration/form_submission_multipart_spec.coffee b/packages/server/test/support/fixtures/projects/e2e/cypress/integration/form_submission_multipart_spec.coffee
new file mode 100644
index 0000000000..20f7bb960a
--- /dev/null
+++ b/packages/server/test/support/fixtures/projects/e2e/cypress/integration/form_submission_multipart_spec.coffee
@@ -0,0 +1,77 @@
+{ Blob, _ } = Cypress
+
+Cypress.Commands.add 'setFile', { prevSubject: "element" }, (element, filePath) ->
+ mimeTypes = {
+ jpeg: "image/jpeg"
+ jpg: "image/jpeg"
+ png: "image/png"
+ pdf: "application/pdf"
+ }
+
+ filePathSplitted = filePath.split('.').pop()
+ mimeType = if mimeTypes[filePathSplitted] != undefined then mimeTypes[filePathSplitted] else null
+
+ fixtureOrReadFile = (filePath) ->
+ if _.startsWith(filePath, "/")
+ return cy.readFile(filePath, "base64")
+
+ return cy.fixture(filePath, "base64")
+
+ return fixtureOrReadFile(filePath).then (image) ->
+ return Blob.base64StringToBlob(image).then (blob) ->
+ elementNode = element[0]
+ file = new File([ blob ], filePath, type: mimeType)
+ dataTransfer = new DataTransfer
+ dataTransfer.items.add(file)
+ elementNode.files = dataTransfer.files
+ elementNode.dispatchEvent new Event("change", { bubbles: true })
+
+describe "
-