diff --git a/.github/workflows/test.yml-template b/.github/workflows/test.yml-template
new file mode 100644
index 0000000000..8b5743ecb4
--- /dev/null
+++ b/.github/workflows/test.yml-template
@@ -0,0 +1,29 @@
+name: Test
+
+on:
+ pull_request:
+ branches: [ master ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [20.x]
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node-version }}
+ - run: npm install
+ - run: npm test
+ - name: Upload HTML report(backstop data)
+ if: ${{ always() }}
+ uses: actions/upload-artifact@v2
+ with:
+ name: report
+ path: backstop_data
diff --git a/backstopConfig.js b/backstopConfig.js
deleted file mode 100644
index 8f0fd08bd3..0000000000
--- a/backstopConfig.js
+++ /dev/null
@@ -1,78 +0,0 @@
-'use strict';
-// https://github.com/garris/BackstopJS#advanced-scenarios
-
-const backstop = require('@mate-academy/backstop-config');
-const { basicScenario } = backstop;
-
-const basic = {
- ...basicScenario,
- label: 'Elementary test',
- referenceUrl: basicScenario.referenceUrl + '/catalog/',
-};
-
-const config = {
- ...backstop,
- fileNameTemplate: '{scenarioLabel}_{viewportLabel}',
- onBeforeScript: 'puppet/onBefore.js',
- onReadyScript: 'puppet/onReady.js',
- viewports: [
- {
- name: '1024px',
- width: 1024,
- height: 768,
- },
- {
- name: '1200px',
- width: 1200,
- height: 768,
- },
- ],
- scenarios: [
- {
- ...basic,
- label: 'Entire document',
- selectors: ['document'],
- },
- {
- ...basic,
- label: 'Header tag',
- selectors: ['header'],
- },
- {
- ...basic,
- label: 'Nav tag',
- selectors: ['nav'],
- },
- {
- ...basic,
- label: 'Link with data-qa_hover',
- selectors: ['[data-qa="nav-hover"]'],
- hoverSelector: '[data-qa="nav-hover"]',
- postInteractionWait: 1000,
- },
- {
- ...basic,
- label: 'Link with class_is-active',
- selectors: ['a.is-active'],
- },
- {
- ...basic,
- label: 'Main tag',
- selectors: ['main'],
- },
- {
- ...basic,
- label: 'Card with data-qa_card',
- selectors: ['[data-qa="card"]'],
- },
- // {
- // ...basic,
- // label: 'Card with data-qa_card-hover',
- // selectors: ['[data-qa="card"]'],
- // hoverSelector: '[data-qa="card-hover"]',
- // postInteractionWait: 1000,
- // },
- ],
-};
-
-module.exports = config;
diff --git a/backstop_data/engine_scripts/cookies.json b/backstop_data/engine_scripts/cookies.json
index b59400d7e6..4123a5d695 100644
--- a/backstop_data/engine_scripts/cookies.json
+++ b/backstop_data/engine_scripts/cookies.json
@@ -9,6 +9,6 @@
"httpOnly": false,
"secure": false,
"session": false,
- "sameSite": "no_restriction"
+ "sameSite": "Lax"
}
]
diff --git a/backstop_data/engine_scripts/puppet/clickAndHoverHelper.js b/backstop_data/engine_scripts/puppet/clickAndHoverHelper.js
index 6c1e1b8841..703d3b89b2 100644
--- a/backstop_data/engine_scripts/puppet/clickAndHoverHelper.js
+++ b/backstop_data/engine_scripts/puppet/clickAndHoverHelper.js
@@ -1,9 +1,9 @@
module.exports = async (page, scenario) => {
- var hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
- var clickSelector = scenario.clickSelectors || scenario.clickSelector;
- var keyPressSelector = scenario.keyPressSelectors || scenario.keyPressSelector;
- var scrollToSelector = scenario.scrollToSelector;
- var postInteractionWait = scenario.postInteractionWait; // selector [str] | ms [int]
+ const hoverSelector = scenario.hoverSelectors || scenario.hoverSelector;
+ const clickSelector = scenario.clickSelectors || scenario.clickSelector;
+ const keyPressSelector = scenario.keyPressSelectors || scenario.keyPressSelector;
+ const scrollToSelector = scenario.scrollToSelector;
+ const postInteractionWait = scenario.postInteractionWait; // selector [str] | ms [int]
if (keyPressSelector) {
for (const keyPressSelectorItem of [].concat(keyPressSelector)) {
@@ -27,7 +27,9 @@ module.exports = async (page, scenario) => {
}
if (postInteractionWait) {
- await new Promise(resolve => setTimeout(resolve, postInteractionWait));
+ await new Promise(resolve => {
+ setTimeout(resolve, postInteractionWait);
+ });
}
if (scrollToSelector) {
diff --git a/backstop_data/engine_scripts/puppet/loadCookies.js b/backstop_data/engine_scripts/puppet/loadCookies.js
deleted file mode 100644
index db848a7cc7..0000000000
--- a/backstop_data/engine_scripts/puppet/loadCookies.js
+++ /dev/null
@@ -1,29 +0,0 @@
-var fs = require('fs');
-
-module.exports = async (page, scenario) => {
- var cookies = [];
- var cookiePath = scenario.cookiePath;
-
- // READ COOKIES FROM FILE IF EXISTS
- if (fs.existsSync(cookiePath)) {
- cookies = JSON.parse(fs.readFileSync(cookiePath));
- }
-
- // MUNGE COOKIE DOMAIN
- cookies = cookies.map(cookie => {
- cookie.url = 'https://' + cookie.domain;
- delete cookie.domain;
- return cookie;
- });
-
- // SET COOKIES
- const setCookies = async () => {
- return Promise.all(
- cookies.map(async (cookie) => {
- await page.setCookie(cookie);
- })
- );
- };
- await setCookies();
- console.log('Cookie state restored with:', JSON.stringify(cookies, null, 2));
-};
diff --git a/javascript.js b/javascript.js
new file mode 100644
index 0000000000..ced058317f
--- /dev/null
+++ b/javascript.js
@@ -0,0 +1,43 @@
+const products = [
+ {
+ imgSrc: 'images/imac.jpeg',
+ altText: 'Apple iMac',
+ title: 'APPLE A1419 iMac 27" Retina 5K Monoblock (MNED2UA/A)',
+ code: '195434',
+ reviews: 5,
+ price: '$2,199',
+ },
+ // Другие карточки
+];
+
+const productContainer = document.getElementById('product-container');
+
+products.forEach((product) => {
+ const card = document.createElement('div');
+ card.className = 'card';
+ card.setAttribute('data-qa', 'card');
+
+ card.innerHTML = `
+
+
${product.title}
+ Product code: ${product.code}
+
+
+
+
+
+
+
+
+
Reviews: ${product.reviews}
+
+
+
Price:
+
${product.price}
+
+ Buy
+ `;
+
+ productContainer.appendChild(card);
+});
+
diff --git a/layout_catalog b/layout_catalog
new file mode 160000
index 0000000000..83bec888ef
--- /dev/null
+++ b/layout_catalog
@@ -0,0 +1 @@
+Subproject commit 83bec888ef2fffa085187a9c48e5452e4326e7eb
diff --git a/package-lock.json b/package-lock.json
index 6dd164c6e0..5525878405 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,10 +14,11 @@
"@mate-academy/backstop-config": "latest",
"@mate-academy/bemlint": "latest",
"@mate-academy/linthtml-config": "latest",
- "@mate-academy/scripts": "^1.8.6",
+ "@mate-academy/scripts": "^1.9.12",
"@mate-academy/stylelint-config": "latest",
"@parcel/transformer-sass": "^2.12.0",
- "backstopjs": "6.3.23",
+ "backstopjs": "^6.3.25",
+ "http-server": "^14.1.1",
"jest": "^29.7.0",
"parcel": "^2.12.0",
"prettier": "^3.3.2",
@@ -1212,10 +1213,11 @@
"dev": true
},
"node_modules/@mate-academy/scripts": {
- "version": "1.8.6",
- "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-1.8.6.tgz",
- "integrity": "sha512-b4om/whj4G9emyi84ORE3FRZzCRwRIesr8tJHXa8EvJdOaAPDpzcJ8A0sFfMsWH9NUOVmOwkBtOXDu5eZZ00Ig==",
+ "version": "1.9.12",
+ "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-1.9.12.tgz",
+ "integrity": "sha512-/OcmxMa34lYLFlGx7Ig926W1U1qjrnXbjFJ2TzUcDaLmED+A5se652NcWwGOidXRuMAOYLPU2jNYBEkKyXrFJA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@octokit/rest": "^17.11.2",
"@types/get-port": "^4.2.0",
@@ -4694,10 +4696,11 @@
}
},
"node_modules/backstopjs": {
- "version": "6.3.23",
- "resolved": "https://registry.npmjs.org/backstopjs/-/backstopjs-6.3.23.tgz",
- "integrity": "sha512-GRSth3jEWI0goJ5ETA+D6QsK7ZZi0+qvZ0AAroGoLODCb20Y7NG3gc0Egnf4Qdrqg4D+seJHVjfZwqm3nuYqZg==",
+ "version": "6.3.25",
+ "resolved": "https://registry.npmjs.org/backstopjs/-/backstopjs-6.3.25.tgz",
+ "integrity": "sha512-jy0dxlk45tItXLcj9zjRTCyCa6D27M9OMK5kM8To0ELLclKhI/dWn/igUTMBBMJXe4Kql+CGyDRErMtTv2+40Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@mirzazeyrek/node-resemble-js": "^1.2.1",
"chalk": "^4.1.2",
@@ -4722,7 +4725,7 @@
"backstop": "cli/index.js"
},
"engines": {
- "node": ">=16.0.0 <=20.x.x",
+ "node": ">=16.0.0",
"npm": ">=8.0.0"
}
},
@@ -4837,6 +4840,26 @@
}
]
},
+ "node_modules/basic-auth": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
+ "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/basic-auth/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/basic-ftp": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
@@ -5393,6 +5416,16 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"dev": true
},
+ "node_modules/corser": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
+ "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
"node_modules/cosmiconfig": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz",
@@ -6147,6 +6180,13 @@
"node": ">= 0.6"
}
},
+ "node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/execa": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@@ -6487,6 +6527,27 @@
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
"dev": true
},
+ "node_modules/follow-redirects": {
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -6838,6 +6899,16 @@
"node": ">= 0.4"
}
},
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "he": "bin/he"
+ }
+ },
"node_modules/hosted-git-info": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
@@ -6868,6 +6939,19 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
+ "node_modules/html-encoding-sniffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
+ "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-encoding": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
@@ -7012,6 +7096,21 @@
"node": ">= 0.8"
}
},
+ "node_modules/http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/http-proxy-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
@@ -7025,6 +7124,51 @@
"node": ">= 14"
}
},
+ "node_modules/http-server": {
+ "version": "14.1.1",
+ "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
+ "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "basic-auth": "^2.0.1",
+ "chalk": "^4.1.2",
+ "corser": "^2.0.1",
+ "he": "^1.2.0",
+ "html-encoding-sniffer": "^3.0.0",
+ "http-proxy": "^1.18.1",
+ "mime": "^1.6.0",
+ "minimist": "^1.2.6",
+ "opener": "^1.5.1",
+ "portfinder": "^1.0.28",
+ "secure-compare": "3.0.1",
+ "union": "~0.5.0",
+ "url-join": "^4.0.1"
+ },
+ "bin": {
+ "http-server": "bin/http-server"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/http-server/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
"node_modules/https-proxy-agent": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
@@ -9168,6 +9312,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/opener": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
+ "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
+ "dev": true,
+ "license": "(WTFPL OR MIT)",
+ "bin": {
+ "opener": "bin/opener-bin.js"
+ }
+ },
"node_modules/opn": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz",
@@ -10271,6 +10425,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/resolve": {
"version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
@@ -10438,6 +10599,13 @@
"node": ">=14.0.0"
}
},
+ "node_modules/secure-compare": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
+ "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
@@ -11456,6 +11624,18 @@
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true
},
+ "node_modules/union": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
+ "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
+ "dev": true,
+ "dependencies": {
+ "qs": "^6.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
"node_modules/universal-user-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
@@ -11511,6 +11691,13 @@
"browserslist": ">= 4.21.0"
}
},
+ "node_modules/url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/urlpattern-polyfill": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz",
@@ -11619,6 +11806,32 @@
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"dev": true
},
+ "node_modules/whatwg-encoding": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
+ "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-encoding/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
diff --git a/package.json b/package.json
index 34398805fa..0c8f327f2a 100644
--- a/package.json
+++ b/package.json
@@ -22,10 +22,11 @@
"@mate-academy/backstop-config": "latest",
"@mate-academy/bemlint": "latest",
"@mate-academy/linthtml-config": "latest",
- "@mate-academy/scripts": "^1.8.6",
+ "@mate-academy/scripts": "^1.9.12",
"@mate-academy/stylelint-config": "latest",
"@parcel/transformer-sass": "^2.12.0",
- "backstopjs": "6.3.23",
+ "backstopjs": "^6.3.25",
+ "http-server": "^14.1.1",
"jest": "^29.7.0",
"parcel": "^2.12.0",
"prettier": "^3.3.2",
diff --git a/readme.md b/readme.md
index 874ca70d97..42d0c455bb 100644
--- a/readme.md
+++ b/readme.md
@@ -9,7 +9,7 @@ Create an HTML page with a catalog. Develop semantic page structure as shown on
- add `data-qa="card-hover"` (not just `hover`) to the link `Buy` inside the first card
- nav links color is not `black` anymore (nav links should have `#060b35` color)
- add the class `is-active` to the first link (`Apple`) in the navigation
-- use `` tag for cards container
+- use `` tag for cards container
- use the grid for cards with different numbers of columns:
- 1 for the smaller screens
- 2 starting at `488px`
@@ -33,8 +33,8 @@ This is possible because [we use the Parcel library](https://en.parceljs.org/scs
## Checklist
❗️ Replace `` with your GitHub username and copy the links to the `Pull Request` description:
-- [DEMO LINK](https://.github.io/layout_catalog/)
-- [TEST REPORT LINK](https://.github.io/layout_catalog/report/html_report/)
+- [DEMO LINK](https://.github.io/layout_catalog/)
+- [TEST REPORT LINK](https://.github.io/layout_catalog/report/html_report/)
❗️ Copy this `Checklist` to the `Pull Request` description after links, and put `- [x]` before each point after you checked it.
diff --git a/src/index.html b/src/index.html
index 9cff78eeb7..cefc1a4553 100644
--- a/src/index.html
+++ b/src/index.html
@@ -17,11 +17,125 @@
/>
-
- Catalog
+
+
+
+
+
+
Product Name
+
Product code: 195434
+
+
+
+ Buy
+
+
+
+
+