From e3766a0ebb3793f1e83d40cf85cf369bcb45ea35 Mon Sep 17 00:00:00 2001 From: Nils Haberkamp Date: Thu, 2 Mar 2023 16:33:07 +0100 Subject: [PATCH 1/3] NEXT-25533 - add limit to textarea component --- .../sw-textarea.interactive.stories.js | 12 +++++ .../form/sw-textarea/sw-textarea.vue | 46 +++++++++++++++++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/components/form/sw-textarea/sw-textarea.interactive.stories.js b/src/components/form/sw-textarea/sw-textarea.interactive.stories.js index 4ead5197..17cdc05b 100644 --- a/src/components/form/sw-textarea/sw-textarea.interactive.stories.js +++ b/src/components/form/sw-textarea/sw-textarea.interactive.stories.js @@ -79,3 +79,15 @@ VisualTestError.play = async ({ args }) => { await expect(canvas.getByText(args.error.detail)).toBeDefined(); }; + +export const VisualTestLimit = Template.bind(); +VisualTestLimit.storyName = 'Should display limit'; +VisualTestLimit.args = { + limit: 45, + value: 'Enter some more text to reach the limit... ' +}; +VisualTestLimit.play = async () => { + const canvas = within(document.getElementById('root')); + + await expect(canvas.getByText('43 / 45')).toBeDefined(); +}; diff --git a/src/components/form/sw-textarea/sw-textarea.vue b/src/components/form/sw-textarea/sw-textarea.vue index e84e26d6..0530d7c9 100644 --- a/src/components/form/sw-textarea/sw-textarea.vue +++ b/src/components/form/sw-textarea/sw-textarea.vue @@ -29,6 +29,7 @@ @input="onInput" @focus="setFocus" @blur="removeFocus" + @keydown="onKeyDown" /> @@ -41,6 +42,13 @@ @@ -114,7 +122,13 @@ export default Vue.extend({ type: Object, required: false, default: null, - } + }, + + limit: { + type: Number, + required: false, + default: null, + }, }, data() { @@ -157,8 +171,12 @@ export default Vue.extend({ methods: { onInput(event: Event) { - // @ts-expect-error - target is defined - this.$emit('input', event.target.value); + const shouldLimit = !!this.limit; + const { value } = event.target as HTMLInputElement; + + const emittedValue = shouldLimit ? value.slice(0, this.limit) : value; + + this.$emit('input', emittedValue); }, onChange(event: Event) { @@ -166,9 +184,27 @@ export default Vue.extend({ this.$emit('change', event.target.value); }, + onKeyDown(event: Event) { + const shouldLimit = !!this.limit; + if (!shouldLimit) { + return; + } + + const exceededLimit = this.currentValue.length >= this.limit; + // @ts-expect-error - key is defined + const pressedBackspace = event.key === 'Backspace'; + + if (exceededLimit && !pressedBackspace) { + // stopping the event from bubbling up will stop the user + // from exceeding the maximum amount of characters + event.preventDefault(); + } + }, + setFocus() { this.hasFocus = true; }, + removeFocus() { this.hasFocus = false; }, @@ -192,5 +228,9 @@ export default Vue.extend({ background: $color-crimson-50; } } + + &__limit { + margin-left: auto; + } } From 0af270f73c7f2183c585316e00bedd3a3b86d634 Mon Sep 17 00:00:00 2001 From: Nils Haberkamp Date: Fri, 3 Mar 2023 09:45:11 +0100 Subject: [PATCH 2/3] NEXT-25533 - fix pipeline --- .github/workflows/deployment.yml | 13 +++-- .github/workflows/npm-publish.yml | 11 ++-- .github/workflows/preview.yml | 15 +++--- .github/workflows/tests.yml | 85 ++++++++++++++++++++----------- package.json | 4 +- 5 files changed, 75 insertions(+), 53 deletions(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 5e5f5f2f..9f984a00 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -1,7 +1,6 @@ name: Deployment -on: - push: +on: pull_request: branches: - main @@ -11,20 +10,20 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: - node-version: 'lts/gallium' + node-version: '18' - name: Retrieve the cached main "node_modules" directory (if present) - uses: actions/cache@v2 + uses: actions/cache@v3 id: node-cache-main with: path: node_modules key: node-modules-main-${{ runner.os }}-${{ hashFiles('package-lock.json') }} - + - name: Install main dependencies (if the cached directory was not found) if: steps.node-cache-main.outputs.cache-hit != 'true' run: npm ci diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 61246972..b510b9c0 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -1,7 +1,6 @@ name: Publish to NPM -on: - push: +on: pull_request: branches: - main @@ -12,13 +11,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: - node-version: 'lts/gallium' + node-version: '18' - name: Retrieve the cached "node_modules" directory (if present) - uses: actions/cache@v2 + uses: actions/cache@v3 id: node-cache with: path: node_modules diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 687b078a..55502a2c 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -1,7 +1,6 @@ name: Deploy PR previews -on: - push: +on: pull_request: types: - opened @@ -16,20 +15,20 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: - node-version: 'lts/gallium' - + node-version: '18' + - name: Retrieve the cached main "node_modules" directory (if present) - uses: actions/cache@v2 + uses: actions/cache@v3 id: node-cache-main with: path: node_modules key: node-modules-main-${{ runner.os }}-${{ hashFiles('package-lock.json') }} - + - name: Install main dependencies (if the cached directory was not found) if: steps.node-cache-main.outputs.cache-hit != 'true' run: npm ci diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 517a59e7..12f1c330 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,7 +1,6 @@ name: Tests -on: - push: +on: pull_request: branches: - main @@ -12,13 +11,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: - node-version: 'lts/gallium' + node-version: '18' - name: Retrieve the cached "node_modules" directory (if present) - uses: actions/cache@v2 + uses: actions/cache@v3 id: node-cache with: path: node_modules @@ -28,32 +27,58 @@ jobs: run: npm ci - name: lint run: npm run lint + unit-tests: + name: Unit tests + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: '18' + - name: Retrieve the cached "node_modules" directory (if present) + uses: actions/cache@v3 + id: node-cache + with: + path: node_modules + key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json') }} + - name: Install dependencies (if the cached directory was not found) + if: steps.node-cache.outputs.cache-hit != 'true' + run: npm ci + - name: unit + run: npm run test:unit storybook-tests: name: Storybook Tests timeout-minutes: 60 runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 - - name: Retrieve the cached "node_modules" directory (if present) - uses: actions/cache@v2 - id: node-cache - with: - path: node_modules - key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json') }} - - name: Install dependencies (if the cached directory was not found) - if: steps.node-cache.outputs.cache-hit != 'true' - run: npm ci - - name: Install Playwright - run: npx playwright install - - name: Run Tests - id: storybookTests - run: npm run test-storybook:ci - - name: Archive visual test diffs - uses: actions/upload-artifact@v3 - if: always() && (steps.storybookTests.outcome == 'failure') - with: - name: visual-test-diffs - path: __snapshots__ \ No newline at end of file + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Node.js + uses: actions/setup-node@v3 + - name: Retrieve the cached "node_modules" directory (if present) + uses: actions/cache@v3 + id: node-cache + with: + path: node_modules + key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json') }} + - name: Install dependencies (if the cached directory was not found) + if: steps.node-cache.outputs.cache-hit != 'true' + run: npm ci + - name: Install Playwright + run: npx playwright install + - name: Create the static pages directory locally in CI + run: npm run build-storybook + - name: Run Tests + id: storybookTests + run: | + npx concurrently --kill-others --success first --names "SB,TEST" --prefix-colors "magenta,blue" \ + "http-server storybook-static -a 127.0.0.1 --port 6006" \ + "wait-on http://127.0.0.1:6006 && npm run test-storybook" + - name: Archive visual test diffs + uses: actions/upload-artifact@v3 + if: always() && (steps.storybookTests.outcome == 'failure') + with: + name: visual-test-diffs + path: __snapshots__ \ No newline at end of file diff --git a/package.json b/package.json index 8c193ce0..12f626a5 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "storybook": "SHOW_INTERACTIONS=true start-storybook -p 6006", "build-vue": "rollup -c", "build-storybook": "build-storybook", - "test-storybook": "test-storybook", - "test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"npm run build-storybook -- --quiet && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && npm run test-storybook\"", + "test-storybook": "test-storybook --url http://127.0.0.1:6006", + "test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"http-server storybook-static -a 127.0.0.1 --port 6006 --silent\" \"wait-on tcp:6006 && npm run test-storybook\"", "docker": "docker run -v $PWD:/tests:delegated -w /tests -it --rm --ipc=host mcr.microsoft.com/playwright:v1.20.0-focal /bin/bash" }, "main": "dist/common/index.js", From 9d8b52ee18d62532f116686f17ae0e47c0f15cbd Mon Sep 17 00:00:00 2001 From: Nils Haberkamp Date: Fri, 3 Mar 2023 10:21:22 +0100 Subject: [PATCH 3/3] NEXT-25533 - add limit to textarea component --- package-lock.json | 96 ++++++++++++++++++++++++++++++++++++++++++++++- package.json | 3 +- 2 files changed, 96 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ab6d9cdd..19438f3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@shopware-ag/meteor-component-library", - "version": "2.0.0", + "version": "2.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@shopware-ag/meteor-component-library", - "version": "2.0.0", + "version": "2.0.1", "dependencies": { "@shopware-ag/meteor-icon-kit": "^4.1.0", "ace-builds": "^1.4.13", @@ -48,6 +48,7 @@ "@vue/eslint-config-airbnb": "^5.0.2", "@vue/eslint-config-typescript": "^11.0.1", "@vue/test-utils": "^1.3.0", + "@vue/vue2-jest": "^27.0.0", "babel-loader": "^8.2.3", "chokidar-cli": "^3.0.0", "concurrently": "^7.1.0", @@ -12796,6 +12797,60 @@ "node": ">=4.0.0" } }, + "node_modules/@vue/vue2-jest": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@vue/vue2-jest/-/vue2-jest-27.0.0.tgz", + "integrity": "sha512-r8YGOuqEWpAf2wGfgxfOL6Jce3WYOMcYji2qd8kuDe466ZsybHFeMryMJi6JrELOOI+MCA/8eFsSOx1KoJa7Dg==", + "dev": true, + "dependencies": { + "@babel/plugin-transform-modules-commonjs": "^7.2.0", + "@vue/component-compiler-utils": "^3.1.0", + "chalk": "^2.1.0", + "css-tree": "^2.0.1", + "source-map": "0.5.6" + }, + "peerDependencies": { + "@babel/core": "7.x", + "babel-jest": ">= 27 < 28", + "jest": "27.x", + "ts-jest": ">= 27 < 28", + "vue": "^2.x", + "vue-template-compiler": "^2.x" + }, + "peerDependenciesMeta": { + "ts-jest": { + "optional": true + } + } + }, + "node_modules/@vue/vue2-jest/node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/@vue/vue2-jest/node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/@vue/vue2-jest/node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@vue/web-component-wrapper": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz", @@ -48984,6 +49039,43 @@ } } }, + "@vue/vue2-jest": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@vue/vue2-jest/-/vue2-jest-27.0.0.tgz", + "integrity": "sha512-r8YGOuqEWpAf2wGfgxfOL6Jce3WYOMcYji2qd8kuDe466ZsybHFeMryMJi6JrELOOI+MCA/8eFsSOx1KoJa7Dg==", + "dev": true, + "requires": { + "@babel/plugin-transform-modules-commonjs": "^7.2.0", + "@vue/component-compiler-utils": "^3.1.0", + "chalk": "^2.1.0", + "css-tree": "^2.0.1", + "source-map": "0.5.6" + }, + "dependencies": { + "css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "requires": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + } + }, + "mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "dev": true + } + } + }, "@vue/web-component-wrapper": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz", diff --git a/package.json b/package.json index 12f626a5..c1ae7854 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "vue-template-compiler": "^2.7.10", "vue-tsc": "^0.39.5", "wait-on": "^6.0.1", - "webpack": "^5.74.0" + "webpack": "^5.74.0", + "@vue/vue2-jest": "^27.0.0" } }