diff --git a/CHANGELOG.md b/CHANGELOG.md index b9de7516..7050200e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - Fix modal close button possition - Fixed an issue with the generation of tranlations - Fix missing spec info when clicking next to a property +- Fix Firefox open file that stopped working due to react upgrade - _...Add new stuff here..._ ## 3.0.0 diff --git a/cypress/e2e/maputnik-cypress-helper.ts b/cypress/e2e/maputnik-cypress-helper.ts index b2a83d31..4ade0c56 100644 --- a/cypress/e2e/maputnik-cypress-helper.ts +++ b/cypress/e2e/maputnik-cypress-helper.ts @@ -26,6 +26,22 @@ export default class MaputnikCypressHelper { this.helper.when.wait(200); this.helper.get.elementByTestId(element).realMouseUp(); }, + openFileByFixture: (fixture: string, buttonTestId: string, inputTestId: string) => { + cy.window().then((win) => { + const file = { + text: cy.stub().resolves(cy.fixture(fixture).then(JSON.stringify)), + }; + const fileHandle = { + getFile: cy.stub().resolves(file), + }; + if (!win.showOpenFilePicker) { + this.helper.get.elementByTestId(inputTestId).selectFile("cypress/fixtures/" + fixture, { force: true }); + } else { + cy.stub(win, "showOpenFilePicker").resolves([fileHandle]); + this.helper.get.elementByTestId(buttonTestId).click(); + } + }); + }, ...this.helper.when, }; diff --git a/cypress/e2e/maputnik-driver.ts b/cypress/e2e/maputnik-driver.ts index c4a5b7e5..dbcb543a 100644 --- a/cypress/e2e/maputnik-driver.ts +++ b/cypress/e2e/maputnik-driver.ts @@ -109,9 +109,9 @@ export class MaputnikDriver { this.helper.when.waitForResponse("example-style.json"); }, chooseExampleFile: () => { - this.helper.get - .bySelector("type", "file") - .selectFile("cypress/fixtures/example-style.json", { force: true }); + this.helper.given.fixture("example-style.json", "example-style.json"); + this.helper.when.openFileByFixture("example-style.json", "modal:open.file.button", "modal:open.file.input"); + this.helper.when.wait(200); }, setStyle: ( styleProperties: "geojson" | "raster" | "both" | "layer" | "rectangles" | "", diff --git a/cypress/e2e/modals.cy.ts b/cypress/e2e/modals.cy.ts index d7f822e9..69517297 100644 --- a/cypress/e2e/modals.cy.ts +++ b/cypress/e2e/modals.cy.ts @@ -18,10 +18,9 @@ describe("modals", () => { then(get.elementByTestId("modal:open")).shouldNotExist(); }); - it.skip("upload", () => { - // HM: I was not able to make the following choose file actually to select a file and close the modal... + it("upload", () => { when.chooseExampleFile(); - then(get.responseBody("example-style.json")).shouldEqualToStoredStyle(); + then(get.fixture("example-style.json")).shouldEqualToStoredStyle(); }); describe("when click open url", () => { @@ -334,6 +333,7 @@ describe("modals", () => { it("add variable", () => { when.click("global-state-add-variable"); + when.wait(100); then(get.styleFromLocalStorage()).shouldDeepNestedInclude({ state: { key1: { default: "value" } }, }); @@ -344,6 +344,7 @@ describe("modals", () => { when.click("global-state-add-variable"); when.click("global-state-add-variable"); when.click("global-state-add-variable"); + when.wait(100); then(get.styleFromLocalStorage()).shouldDeepNestedInclude({ state: { key1: { default: "value" }, key2: { default: "value" }, key3: { default: "value" } }, }); @@ -354,6 +355,7 @@ describe("modals", () => { when.click("global-state-add-variable"); when.click("global-state-add-variable"); when.click("global-state-remove-variable", 0); + when.wait(100); then(get.styleFromLocalStorage()).shouldDeepNestedInclude({ state: { key2: { default: "value" }, key3: { default: "value" } }, }); @@ -363,6 +365,7 @@ describe("modals", () => { when.click("global-state-add-variable"); when.setValue("global-state-variable-key:0", "mykey"); when.typeKeys("{enter}"); + when.wait(100); then(get.styleFromLocalStorage()).shouldDeepNestedInclude({ state: { mykey: { default: "value" } }, }); @@ -372,6 +375,7 @@ describe("modals", () => { when.click("global-state-add-variable"); when.setValue("global-state-variable-value:0", "myvalue"); when.typeKeys("{enter}"); + when.wait(100); then(get.styleFromLocalStorage()).shouldDeepNestedInclude({ state: { key1: { default: "myvalue" } }, }); diff --git a/package-lock.json b/package-lock.json index ff4ff647..68c4b349 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,6 @@ "react-collapse": "^5.1.1", "react-color": "^2.19.3", "react-dom": "^19.1.1", - "react-file-reader-input": "^2.0.0", "react-i18next": "^15.7.3", "react-icons": "^5.5.0", "react-markdown": "^10.1.0", @@ -86,7 +85,6 @@ "@types/react-collapse": "^5.0.4", "@types/react-color": "^3.0.13", "@types/react-dom": "^19.1.9", - "@types/react-file-reader-input": "^2.0.4", "@types/string-hash": "^1.1.3", "@types/uuid": "^10.0.0", "@types/wicg-file-system-access": "^2023.10.6", @@ -3225,15 +3223,6 @@ "@types/react": "^19.0.0" } }, - "node_modules/@types/react-file-reader-input": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/react-file-reader-input/-/react-file-reader-input-2.0.4.tgz", - "integrity": "sha512-Jqrfn+w42j8t8Q3npMXXKPdk+reIM0UHLKVc3ykrA7q7bN3Z62SGhsClZX0+Edlqm66lcKwmDQl+WMm+Xor7Xg==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/reactcss": { "version": "1.2.12", "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.12.tgz", @@ -11681,15 +11670,6 @@ "react": "^19.1.1" } }, - "node_modules/react-file-reader-input": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/react-file-reader-input/-/react-file-reader-input-2.0.0.tgz", - "integrity": "sha512-1XgkCpwMnNQsuOIy938UCntz8Xzwt9ECwHaH3cCfIQK1SPpH+y7gCYtqEcb6Rm0hAUq7Lp9+Ljoti9zGMswYrQ==", - "peerDependencies": { - "react": "^15.0.0 || ^16.0.0", - "react-dom": "^15.0.0 || ^16.0.0" - } - }, "node_modules/react-hot-loader": { "version": "4.13.1", "resolved": "https://registry.npmjs.org/react-hot-loader/-/react-hot-loader-4.13.1.tgz", diff --git a/package.json b/package.json index 1d8b67b0..be41d98c 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,6 @@ "react-collapse": "^5.1.1", "react-color": "^2.19.3", "react-dom": "^19.1.1", - "react-file-reader-input": "^2.0.0", "react-i18next": "^15.7.3", "react-icons": "^5.5.0", "react-markdown": "^10.1.0", @@ -118,7 +117,6 @@ "@types/react-collapse": "^5.0.4", "@types/react-color": "^3.0.13", "@types/react-dom": "^19.1.9", - "@types/react-file-reader-input": "^2.0.4", "@types/string-hash": "^1.1.3", "@types/uuid": "^10.0.0", "@types/wicg-file-system-access": "^2023.10.6", diff --git a/src/components/modals/ModalOpen.tsx b/src/components/modals/ModalOpen.tsx index e8f07d00..9bee6592 100644 --- a/src/components/modals/ModalOpen.tsx +++ b/src/components/modals/ModalOpen.tsx @@ -1,7 +1,6 @@ import React, { type FormEvent } from "react"; import {MdFileUpload} from "react-icons/md"; import {MdAddCircleOutline} from "react-icons/md"; -import FileReaderInput, { type Result } from "react-file-reader-input"; import { Trans, type WithTranslation, withTranslation } from "react-i18next"; import ModalLoading from "./ModalLoading"; @@ -171,8 +170,10 @@ class ModalOpenInternal extends React.Component { - const [, file] = files[0]; + onFileChanged = (files: FileList | null) => { + if (!files) return; + if (files.length === 0) return; + const file = files[0]; const reader = new FileReader(); this.clearError(); @@ -246,13 +247,15 @@ class ModalOpenInternal extends React.Component {typeof window.showOpenFilePicker === "function" ? ( {t("Open Style")} ) : ( - - {t("Open Style")} - + )}