diff --git a/README.md b/README.md
index 0793506..883f912 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,6 @@ recipeScraper("some.recipe.url").then(recipe => {
- https://copykat.com/
- https://damndelicious.net/
- https://www.eatingwell.com/
-- https://www.epicurious.com/
- https://www.food.com/
- https://www.foodandwine.com/
- https://www.foodnetwork.com/
@@ -78,7 +77,8 @@ recipeScraper("some.recipe.url").then(recipe => {
- https://www.yummly.com/
- https://www.jamieoliver.com/
-Don't see a website you'd like to scrape? Open an [issue](https://github.com/jadkins89/Recipe-Scraper/issues) and we'll do our best to add it.
+And many more! the list above is old fashioned scraping, but for all those websites who have google recipe ld json included, it will also work.
+
## Recipe Object
@@ -105,6 +105,8 @@ Depending on the recipe, certain fields may be left blank. All fields are repres
## Error Handling
+If a recipe is not found on the given url, the basic page info will be returned: title, image & description.
+
If the url provided is invalid and a domain is unable to be parsed, an error message will be returned.
```javascript
@@ -114,24 +116,6 @@ recipeScraper("keyboard kitty").catch(error => {
});
```
-If the url provided doesn't match a supported domain, an error message will be returned.
-
-```javascript
-recipeScraper("some.invalid.url").catch(error => {
- console.log(error.message);
- // => "Site not yet supported"
-});
-```
-
-If a recipe is not found on a supported domain site, an error message will be returned.
-
-```javascript
-recipeScraper("some.no.recipe.url").catch(error => {
- console.log(error.message);
- // => "No recipe found on page"
-});
-```
-
If a page does not exist or some other 400+ error occurs when fetching, an error message will be returned.
```javascript
@@ -150,6 +134,8 @@ recipeScraper("some.improper.url").catch(error => {
});
```
+
+
## Bugs
With web scraping comes a reliance on the website being used not changing format. If this occurs we need to update our scrape. Please reach out if you are experiencing an issue.
diff --git a/helpers/BaseScraper.js b/helpers/BaseScraper.js
index c137804..a7c79b9 100644
--- a/helpers/BaseScraper.js
+++ b/helpers/BaseScraper.js
@@ -22,7 +22,7 @@ class BaseScraper {
return res.ok; // res.status >= 200 && res.status < 300
} catch (e) {
- console.log(e)
+ // console.log(e)
return false;
}
}
@@ -47,6 +47,192 @@ class BaseScraper {
throw new Error("No recipe found on page");
}
+ /**
+ * look for LD+JOSN script in the web page.
+ * @param {object} $ - a cheerio object representing a DOM
+ * @returns {boolean} - if exist, set recipe data and return true, else - return false.
+ */
+ defaultLD_JOSN($) {
+ const jsonLDs = Object.values($("script[type='application/ld+json']"));
+ let isRecipeSchemaFound = false;
+
+ jsonLDs.forEach(jsonLD => {
+ if (jsonLD && jsonLD.children && Array.isArray(jsonLD.children)) {
+ jsonLD.children.forEach(el => {
+ if (el.data) {
+
+ const jsonRaw = el.data;
+ const result = JSON.parse(jsonRaw);
+ let recipe;
+
+
+
+ if (result['@graph'] && Array.isArray(result['@graph'])) {
+ result['@graph'].forEach(g => {
+ if (g['@type'] === 'Recipe') {
+ recipe = g;
+ }
+ })
+ }
+
+ if (result['@type'] === 'Recipe') {
+ recipe = result;
+ }
+
+ if (Array.isArray(result['@type']) && result['@type'].includes('Recipe')) {
+ recipe = result;
+ }
+
+ if (recipe) {
+ // console.log('found a Recipe type json schema!');
+ try {
+ // name
+ this.recipe.name = BaseScraper.HtmlDecode($, recipe.name);
+
+ // description
+ if (recipe.description) {
+ this.recipe.description = BaseScraper.HtmlDecode($, recipe.description);
+ } else {
+ this.defaultSetDescription($);
+ }
+
+ // image
+ if (Array.isArray(recipe.image)) {
+ recipe.image = recipe.image[0];
+ }
+
+ if (recipe.image) {
+ if (recipe.image["@type"] === "ImageObject" && recipe.image.url) {
+ this.recipe.image = recipe.image.url;
+ } else if (typeof recipe.image === "string") {
+ this.recipe.image = recipe.image;
+ }
+ } else {
+ this.defaultSetImage($);
+ }
+
+
+ // tags
+ this.recipe.tags = [];
+ if (recipe.keywords) {
+ if (typeof recipe.keywords === "string") {
+ this.recipe.tags = [...recipe.keywords.split(',')]
+ } else if (Array.isArray(recipe.keywords)) {
+ this.recipe.tags = [...recipe.keywords]
+ }
+ }
+
+ if (recipe.recipeCuisine) {
+ if (typeof recipe.recipeCuisine === "string") {
+ this.recipe.tags.push(recipe.recipeCuisine)
+ } else if (Array.isArray(recipe.recipeCuisine)) {
+ this.recipe.tags = [...new Set([...this.recipe.tags, ...recipe.recipeCuisine])]
+ }
+ }
+
+ if (recipe.recipeCategory) {
+ if (typeof recipe.recipeCategory === "string") {
+ this.recipe.tags.push(recipe.recipeCategory)
+ } else if (Array.isArray(recipe.recipeCategory)) {
+ this.recipe.tags = [...new Set([...this.recipe.tags, ...recipe.recipeCategory])]
+ }
+ }
+
+ this.recipe.tags = this.recipe.tags.map(i => BaseScraper.HtmlDecode($, i));
+ this.recipe.tags = [...new Set(this.recipe.tags)];
+
+ // ingredients
+ if (Array.isArray(recipe.recipeIngredient)) {
+ this.recipe.ingredients = recipe.recipeIngredient.map(i => BaseScraper.HtmlDecode($, i));
+ } else if (typeof recipe.recipeIngredient === "string") {
+ this.recipe.ingredients = recipe.recipeIngredient.split(",").map(i => BaseScraper.HtmlDecode($, i.trim()));
+ }
+
+ // instructions (may be string, array of strings, or object of sectioned instructions)
+ this.recipe.instructions = [];
+ this.recipe.sectionedInstructions = [];
+
+ if (recipe.recipeInstructions &&
+ recipe.recipeInstructions["@type"] === "ItemList" &&
+ recipe.recipeInstructions.itemListElement) {
+
+ recipe.recipeInstructions.itemListElement.forEach(section => {
+ this.recipe.instructions = [
+ ...this.recipe.instructions,
+ ...section.itemListElement.map(i => BaseScraper.HtmlDecode($, i.text))
+ ];
+ section.itemListElement.forEach(i => {
+ this.recipe.sectionedInstructions.push({
+ sectionTitle: section.name,
+ text: BaseScraper.HtmlDecode($, i.text),
+ image: i.image || ''
+ })
+ });
+ });
+ } else if (Array.isArray(recipe.recipeInstructions)) {
+ recipe.recipeInstructions.forEach(instructionStep => {
+ if (instructionStep["@type"] === "HowToStep") {
+ this.recipe.instructions.push(BaseScraper.HtmlDecode($, instructionStep.text));
+ this.recipe.sectionedInstructions.push({
+ sectionTitle: instructionStep.name || '',
+ text: BaseScraper.HtmlDecode($, instructionStep.text),
+ image: instructionStep.image || ''
+ })
+ } else if (instructionStep["@type"] === "HowToSection") {
+ if (instructionStep.itemListElement) {
+ instructionStep.itemListElement.forEach(step => {
+ this.recipe.instructions.push(BaseScraper.HtmlDecode($, step.text));
+
+ this.recipe.sectionedInstructions.push({
+ sectionTitle: instructionStep.name,
+ text: BaseScraper.HtmlDecode($, step.text),
+ image: step.image || ''
+ })
+ });
+ }
+ } else if (typeof instructionStep === "string") {
+ this.recipe.instructions.push(BaseScraper.HtmlDecode($, instructionStep));
+ }
+ });
+ } else if (typeof recipe.recipeInstructions === "string") {
+ this.recipe.instructions = [BaseScraper.HtmlDecode($, recipe.recipeInstructions)]
+ }
+
+ // prep time
+ if (recipe.prepTime) {
+ this.recipe.time.prep = BaseScraper.parsePTTime(recipe.prepTime);
+ }
+
+ // cook time
+ if (recipe.cookTime) {
+ this.recipe.time.cook = BaseScraper.parsePTTime(recipe.cookTime);
+ }
+
+ // total time
+ if (recipe.totalTime) {
+ this.recipe.time.total = BaseScraper.parsePTTime(recipe.totalTime);
+ }
+
+ // servings
+ if (Array.isArray(recipe.recipeYield)) {
+ this.recipe.servings = recipe.recipeYield[0];
+ } else if (typeof recipe.recipeYield === "string") {
+ this.recipe.servings = recipe.recipeYield;
+ }
+
+ isRecipeSchemaFound = true;
+ } catch (e) {
+ console.log(e);
+ }
+ }
+ }
+ });
+ }
+ });
+
+ return isRecipeSchemaFound;
+ }
+
/**
* @param {object} $ - a cheerio object representing a DOM
* @returns {string|null} - if found, an image url
@@ -58,6 +244,21 @@ class BaseScraper {
$("meta[itemprop='image']").attr("content");
}
+ /**
+ * @param {object} $ - a cheerio object representing a DOM
+ * if found, set recipe name
+ */
+ defaultSetName($) {
+ let title =
+ $("meta[name='title']").attr("content") ||
+ $("meta[property='og:title']").attr("content") ||
+ $("meta[name='twitter:title']").attr("content");
+
+ title = title.split('|')[0];
+
+ this.recipe.name = title ? title.trim() : '';
+ }
+
/**
* @param {object} $ - a cheerio object representing a DOM
* if found, set recipe description
@@ -77,11 +278,16 @@ class BaseScraper {
*/
async fetchDOMModel() {
try {
- const res = await fetch(this.url);
+ const meta = [
+ ['User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.2 Safari/605.1.15'],
+ ];
+ const headers = new fetch.Headers(meta);
+ const res = await fetch(this.url, {headers});
const html = await res.text();
return cheerio.load(html);
} catch (err) {
- this.defaultError();
+ throw err;
+ // this.defaultError();
}
}
@@ -91,9 +297,15 @@ class BaseScraper {
*/
async fetchRecipe() {
this.checkUrl();
- const $ = await this.fetchDOMModel();
- this.createRecipeObject();
- this.scrape($);
+ try {
+ const $ = await this.fetchDOMModel();
+ this.createRecipeObject();
+ this.scrape($);
+ } catch (e) {
+ // throw e;
+ this.defaultError();
+ }
+
return this.validateRecipe();
}
@@ -110,6 +322,15 @@ class BaseScraper {
return el.text().trim();
}
+ static HtmlDecode($, s) {
+ const res = $('
').html(s).text() || "";
+
+ return res.trim()
+ .replace(/amp;/gm, '')
+ .replace(/(?=\[caption).*?(?<=\[ caption\])/g, '') // removes short-codes [caption.*[ caption]
+ .replace(/\n/g, "");
+ }
+
/**
* Validates scraped recipes against defined recipe schema
* @returns {object} - an object representing the recipe
@@ -117,6 +338,9 @@ class BaseScraper {
validateRecipe() {
let res = validate(this.recipe, recipeSchema);
if (!res.valid) {
+ // res.errors.forEach(error => {
+ // console.log(error.property + ' ' + error.message);
+ // });
this.defaultError();
}
return this.recipe;
@@ -124,11 +348,11 @@ class BaseScraper {
static parsePTTime(ptTime) {
ptTime = ptTime.replace('PT', '');
- ptTime = ptTime.replace('H', ' hours');
- ptTime = ptTime.replace('M', ' minutes');
+ ptTime = ptTime.replace('H', ' hours ');
+ ptTime = ptTime.replace('M', ' minutes ');
ptTime = ptTime.replace('S', ' seconds');
- return ptTime;
+ return ptTime.trim();
}
}
diff --git a/helpers/DefaultLdJsonScraper.js b/helpers/DefaultLdJsonScraper.js
new file mode 100644
index 0000000..2c8cf9a
--- /dev/null
+++ b/helpers/DefaultLdJsonScraper.js
@@ -0,0 +1,31 @@
+const BaseScraper = require("./BaseScraper");
+
+class DefaultLdJsonScraper extends BaseScraper {
+
+ // async customPoll(page) {
+ // let container,
+ // count = 0;
+ // do {
+ // container = await page.$("script[type='application/ld+json']");
+ // if (!container) {
+ // await page.waitForTimeout(100);
+ // count++;
+ // }
+ // } while (!container && count < 60);
+ // return true;
+ // }
+
+ scrape($) {
+ const isSchemaFound = this.defaultLD_JOSN($);
+
+ if (!isSchemaFound) {
+ // throw new Error("Site not yet supported");
+ // if no recipe schema was found, return the basic page info
+ this.defaultSetName($);
+ this.defaultSetDescription($);
+ this.defaultSetImage($);
+ }
+ }
+}
+
+module.exports = DefaultLdJsonScraper;
diff --git a/helpers/PuppeteerScraper.js b/helpers/PuppeteerScraper.js
index 4e189da..81be787 100644
--- a/helpers/PuppeteerScraper.js
+++ b/helpers/PuppeteerScraper.js
@@ -86,7 +86,8 @@ class PuppeteerScraper extends BaseScraper {
});
if (response._status >= 400) {
- this.defaultError()
+ // throw new Error("Server not responding");
+ this.defaultError();
}
return cheerio.load(html);
}
diff --git a/helpers/RecipeSchema.json b/helpers/RecipeSchema.json
index f21ba0f..b4dc6a0 100644
--- a/helpers/RecipeSchema.json
+++ b/helpers/RecipeSchema.json
@@ -10,15 +10,24 @@
},
"ingredients": {
"type": "array",
- "minItems": 1,
"items": { "type": "string" }
},
"instructions": {
"type": "array",
- "minItems": 1,
- "uniqueItems": true,
"items": { "type": "string" }
},
+ "sectionedInstructions": {
+ "type": "array",
+ "uniqueItems": true,
+ "items": {
+ "type": "object",
+ "properties": {
+ "sectionTitle": { "type": "string"},
+ "text": { "type": "string"},
+ "image": { "type": "string"}
+ }
+ }
+ },
"tags": {
"type": "array",
"uniqueItems": true,
diff --git a/helpers/ScraperFactory.js b/helpers/ScraperFactory.js
index b1d3719..f340352 100644
--- a/helpers/ScraperFactory.js
+++ b/helpers/ScraperFactory.js
@@ -1,6 +1,7 @@
"use strict";
const parseDomain = require("parse-domain");
+const defaultLdJsonScraper = require('./DefaultLdJsonScraper');
const domains = {
"101cookbooks": require("../scrapers/101CookbooksScraper"),
@@ -17,11 +18,9 @@ const domains = {
copykat: require("../scrapers/CopyKatScraper"),
damndelicious: require("../scrapers/DamnDeliciousScraper"),
eatingwell: require("../scrapers/EatingWellScraper"),
- epicurious: require("../scrapers/EpicuriousScraper"),
food: require("../scrapers/FoodScraper"),
foodandwine: require("../scrapers/FoodAndWineScraper"),
foodnetwork: require("../scrapers/FoodNetworkScraper"),
- gimmedelicious: require("../scrapers/GimmeDeliciousScraper"),
gimmesomeoven: require("../scrapers/GimmeSomeOvenScraper"),
julieblanner: require("../scrapers/JulieBlannerScraper"),
kitchenstories: require("../scrapers/KitchenStoriesScraper"),
@@ -33,7 +32,6 @@ const domains = {
pinchofyum: require("../scrapers/PinchOfYumScraper"),
recipetineats: require("../scrapers/RecipeTinEatsScraper"),
seriouseats: require("../scrapers/SeriousEatsScraper"),
- simplyrecipes: require("../scrapers/SimplyRecipesScraper"),
smittenkitchen: require("../scrapers/SmittenKitchenScraper"),
tastesbetterfromscratch: require("../scrapers/TastesBetterFromScratchScraper"),
tasteofhome: require("../scrapers/TasteOfHomeScraper"),
@@ -60,7 +58,7 @@ class ScraperFactory {
if (domains[domain] !== undefined) {
return new domains[domain](url);
} else {
- throw new Error("Site not yet supported");
+ return new defaultLdJsonScraper(url);
}
} else {
throw new Error("Failed to parse domain");
diff --git a/package.json b/package.json
index 956085a..379d29f 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,7 @@
],
"main": "scrapers/index.js",
"scripts": {
- "test": "mocha --timeout 15000",
+ "test": "mocha --timeout 30000",
"start": "node scrapers/index.js",
"coverage": "nyc npm test",
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls"
@@ -36,7 +36,7 @@
"jsonschema": "^1.4.0",
"node-fetch": "^2.6.1",
"parse-domain": "^2.3.2",
- "puppeteer": "^9.0.0"
+ "puppeteer": "^10.2.0"
},
"devDependencies": {
"chai": "^4.2.0",
diff --git a/scrapers/AllRecipesScraper.js b/scrapers/AllRecipesScraper.js
index b8cfaba..7b87234 100644
--- a/scrapers/AllRecipesScraper.js
+++ b/scrapers/AllRecipesScraper.js
@@ -19,7 +19,8 @@ class AllRecipesScraper extends BaseScraper {
const value = $(el)
.children(".recipe-meta-item-body")
.text()
- .replace(/\s\s+/g, "");
+ .replace(/\s\s+/g, "")
+ .trim();
switch (title) {
case "prep":
time.prep = value;
diff --git a/scrapers/BonAppetitScraper.js b/scrapers/BonAppetitScraper.js
index ff94414..6e472e5 100644
--- a/scrapers/BonAppetitScraper.js
+++ b/scrapers/BonAppetitScraper.js
@@ -12,34 +12,7 @@ class BonAppetitScraper extends BaseScraper {
}
scrape($) {
- this.defaultSetImage($);
- this.defaultSetDescription($);
- const { ingredients, instructions } = this.recipe;
-
- this.recipe.name = $("meta[property='og:title']").attr("content");
- const tags = $("meta[name='keywords']").attr("content");
-
- this.recipe.tags = tags ? tags.split(',') : [];
-
- const container = $('div[data-testid="IngredientList"]');
- const ingredientsContainer = container.children("div");
- const units = ingredientsContainer.children("p");
- const ingrDivs = ingredientsContainer.children("div");
-
- units.each((i, el) => {
- ingredients.push(`${$(el).text()} ${$(ingrDivs[i]).text()}`);
- });
-
- const instructionContainer = $('div[data-testid="InstructionsWrapper"]');
-
- instructionContainer.find("p").each((i, el) => {
- instructions.push($(el).text());
- });
-
- this.recipe.servings = container
- .children("p")
- .text()
- .split(" ")[0];
+ this.defaultLD_JOSN($);
}
}
diff --git a/scrapers/EatingWellScraper.js b/scrapers/EatingWellScraper.js
index 0be5210..c7e7744 100644
--- a/scrapers/EatingWellScraper.js
+++ b/scrapers/EatingWellScraper.js
@@ -60,7 +60,8 @@ class EatingWellScraper extends BaseScraper {
.children(".recipe-meta-item-body")
.text()
.replace(/\s\s+/g, "")
- .replace(/\n/g, "");
+ .replace(/\n/g, "")
+ .trim();
switch (title) {
case "prep":
time.prep = value;
diff --git a/scrapers/EpicuriousScraper.js b/scrapers/EpicuriousScraper.js
deleted file mode 100644
index 0811498..0000000
--- a/scrapers/EpicuriousScraper.js
+++ /dev/null
@@ -1,45 +0,0 @@
-"use strict";
-
-const BaseScraper = require("../helpers/BaseScraper");
-
-/**
- * Class for scraping epicurious.com
- * @extends BaseScraper
- */
-class EpicuriousScraper extends BaseScraper {
- constructor(url) {
- super(url, "epicurious.com/recipes/");
- }
-
- scrape($) {
- this.defaultSetImage($);
- this.defaultSetDescription($);
- const { ingredients, instructions, tags, time } = this.recipe;
- this.recipe.name = $("h1[itemprop=name]")
- .text()
- .trim();
-
- $(".ingredient").each((i, el) => {
- ingredients.push($(el).text());
- });
-
- $(".preparation-step").each((i, el) => {
- instructions.push(
- $(el)
- .text()
- .replace(/\s\s+/g, "")
- );
- });
-
- $("dt[itemprop=recipeCategory]").each((i, el) => {
- tags.push($(el).text());
- });
-
- time.active = $("dd.active-time").text();
- time.total = $("dd.total-time").text();
-
- this.recipe.servings = $("dd.yield").text();
- }
-}
-
-module.exports = EpicuriousScraper;
diff --git a/scrapers/GimmeDeliciousScraper.js b/scrapers/GimmeDeliciousScraper.js
deleted file mode 100644
index a523065..0000000
--- a/scrapers/GimmeDeliciousScraper.js
+++ /dev/null
@@ -1,57 +0,0 @@
-"use strict";
-
-const BaseScraper = require("../helpers/BaseScraper");
-
-/**
- * Class for scraping gimmedelicious.com
- * @extends BaseScraper
- */
-class GimmeDeliciousScraper extends BaseScraper {
- constructor(url) {
- super(url, "gimmedelicious.com/");
- }
-
- scrape($) {
- this.defaultSetImage($);
- this.recipe.description = this.textTrim($('.entry-content em').first());
- const { ingredients, instructions, time } = this.recipe;
- this.recipe.name = this.textTrim($(".wprm-recipe-name"));
-
- this.recipe.tags = ($("meta[name='keywords']").attr("content") || "").split(
- ","
- );
-
- $(".wprm-recipe-ingredients > .wprm-recipe-ingredient").each((i, el) => {
- ingredients.push(
- $(el)
- .text()
- .replace(/▢/g, "")
- );
- });
-
- $(".wprm-recipe-instruction-text").each((i, el) => {
- instructions.push(
- $(el)
- .remove("img")
- .text()
- .trim()
- );
- });
-
- time.prep =
- $(".wprm-recipe-prep_time-minutes").text() +
- " " +
- $(".wprm-recipe-prep_timeunit-minutes").text();
- time.cook =
- $(".wprm-recipe-cook_time-minutes").text() +
- " " +
- $(".wprm-recipe-cook_timeunit-minutes").text();
- time.total =
- $(".wprm-recipe-total_time-minutes").text() +
- " " +
- $(".wprm-recipe-total_timeunit-minutes").text();
- this.recipe.servings = $(".wprm-recipe-servings").text();
- }
-}
-
-module.exports = GimmeDeliciousScraper;
diff --git a/scrapers/MelsKitchenCafeScraper.js b/scrapers/MelsKitchenCafeScraper.js
index dbde527..f892e43 100644
--- a/scrapers/MelsKitchenCafeScraper.js
+++ b/scrapers/MelsKitchenCafeScraper.js
@@ -12,50 +12,10 @@ class MelsKitchenCafeScraper extends BaseScraper {
}
scrape($) {
- this.defaultSetImage($);
- this.defaultSetDescription($);
- const { ingredients, instructions, time } = this.recipe;
-
- // get tags from json schema
- const jsonLD = $("script[type='application/ld+json']:not(.yoast-schema-graph)")[0];
- if (jsonLD && jsonLD.children && jsonLD.children[0].data) {
- const jsonRaw = jsonLD.children[0].data;
- const result = JSON.parse(jsonRaw);
-
- if (result && result.keywords) {
- this.recipe.tags = result.keywords.split(',').map(t => t.trim());
- }
- if (result && result.recipeCategory) {
- this.recipe.tags.push(result.recipeCategory);
- }
- }
-
- this.recipe.name = this.textTrim(
- $(".wp-block-mv-recipe .mv-create-title-primary")
- );
-
- $("div.mv-create-ingredients ul li").each((i, el) => {
- ingredients.push(this.textTrim($(el)));
- });
+ this.defaultLD_JOSN($);
+ }
- $("div.mv-create-instructions ol li").each((i, el) => {
- instructions.push(this.textTrim($(el)));
- });
- time.prep = this.textTrim($(".mv-create-time-prep .mv-create-time-format"));
- time.cook = this.textTrim(
- $(".mv-create-time-active .mv-create-time-format")
- );
- time.inactive = this.textTrim(
- $(".mv-create-time-additional .mv-create-time-format")
- );
- time.total = this.textTrim(
- $(".mv-create-time-total .mv-create-time-format")
- );
- this.recipe.servings = this.textTrim(
- $(".mv-create-time-yield .mv-create-time-format")
- );
- }
}
module.exports = MelsKitchenCafeScraper;
diff --git a/scrapers/SimplyRecipesScraper.js b/scrapers/SimplyRecipesScraper.js
deleted file mode 100644
index c1e4559..0000000
--- a/scrapers/SimplyRecipesScraper.js
+++ /dev/null
@@ -1,65 +0,0 @@
-"use strict";
-
-const BaseScraper = require("../helpers/BaseScraper");
-
-/**
- * Class for scraping simplyrecipes.com
- * @extends BaseScraper
- */
-class SimplyRecipesScraper extends BaseScraper {
- constructor(url) {
- super(url, "simplyrecipes.com/recipes/");
- }
-
- scrape($) {
- this.defaultSetImage($);
- this.defaultSetDescription($);
- const { ingredients, instructions, time } = this.recipe;
- this.recipe.name = $("#recipe-block__header_1-0").text();
-
- $("li.ingredient").each((i, el) => {
- ingredients.push(this.textTrim($(el)));
- });
-
- $("#structured-project__steps_1-0")
- .find("p")
- .each((i, el) => {
- instructions.push(
- $(el)
- .text()
- .trim()
- );
- });
-
- time.prep = this.textTrim($(".prep-time .meta-text__data")).replace(
- "\n",
- " "
- );
-
- time.active = this.textTrim($(".active-time .meta-text__data")).replace(
- "\n",
- " "
- );
-
- time.inactive = this.textTrim($(".custom-time .meta-text__data")).replace(
- "\n",
- " "
- );
-
- time.cook = this.textTrim($(".cook-time .meta-text__data")).replace(
- "\n",
- " "
- );
-
- time.total = this.textTrim($(".total-time .meta-text__data")).replace(
- "\n",
- " "
- );
-
- this.recipe.servings = this.textTrim(
- $(".recipe-serving .meta-text__data")
- ).replace("\n", " ");
- }
-}
-
-module.exports = SimplyRecipesScraper;
diff --git a/scrapers/TasteOfHomeScraper.js b/scrapers/TasteOfHomeScraper.js
index 6029118..72eaa4b 100644
--- a/scrapers/TasteOfHomeScraper.js
+++ b/scrapers/TasteOfHomeScraper.js
@@ -12,31 +12,11 @@ class TasteOfHomeScraper extends BaseScraper {
}
scrape($) {
- this.defaultSetImage($);
- this.defaultSetDescription($);
- const { ingredients, instructions, tags, time } = this.recipe;
- this.recipe.name = $("h1.recipe-title")
- .text()
- .trim();
+ this.defaultLD_JOSN($);
- $("meta[property='article:tag']").each((i, el) => {
- tags.push($(el).attr("content"));
+ $("script[data-article-tags]").each((i, el) => {
+ this.recipe.tags = [...new Set([...this.recipe.tags, ...el.attribs['data-article-tags'].split(', ')])];
});
-
- $(".recipe-ingredients__list li").each((i, el) => {
- ingredients.push($(el).text());
- });
-
- $(".recipe-directions__item").each((i, el) => {
- instructions.push(this.textTrim($(el)));
- });
-
- let timeStr = $(".recipe-time-yield__label-prep")
- .text()
- .split(/Bake:/g);
- time.prep = timeStr[0].replace("Prep:", "").trim();
- time.cook = (timeStr[1] || "").trim();
- this.recipe.servings = $(".recipe-time-yield__label-servings").text().trim();
}
}
diff --git a/scrapers/TastesBetterFromScratchScraper.js b/scrapers/TastesBetterFromScratchScraper.js
index 7f6f113..e2a1601 100644
--- a/scrapers/TastesBetterFromScratchScraper.js
+++ b/scrapers/TastesBetterFromScratchScraper.js
@@ -47,16 +47,9 @@ class TastesBetterFromScratchScraper extends PuppeteerScraper {
);
});
- $(".wprm-recipe-time-container").each((i, el) => {
- let text = $(el).text();
- if (text.includes("Total Time:")) {
- time.total = text.replace("Total Time:", "").trim();
- } else if (text.includes("Prep Time:")) {
- time.prep = text.replace("Prep Time:", "").trim();
- } else if (text.includes("Cook Time:")) {
- time.cook = text.replace("Cook Time:", "").trim();
- }
- });
+ time.prep = $(".wprm-recipe-prep-time-container").text().replace('Prep', '').trim();
+ time.cook = $(".wprm-recipe-cook-time-container").text().replace('Cook', '').trim();
+ time.total = $(".wprm-recipe-total-time-container").text().replace('Total', '').trim();
this.recipe.servings = $(".wprm-recipe-servings").text() || "";
}
diff --git a/scrapers/WoolworthsScraper.js b/scrapers/WoolworthsScraper.js
index efa22d5..77c9c08 100644
--- a/scrapers/WoolworthsScraper.js
+++ b/scrapers/WoolworthsScraper.js
@@ -8,68 +8,19 @@ const PuppeteerScraper = require("../helpers/PuppeteerScraper");
*/
class WoolworthsScraper extends PuppeteerScraper {
constructor(url) {
- super(url, "woolworths.com.au/shop/recipedetail/");
+ super(url, "woolworths.com.au/shop/recipes/");
}
async customPoll(page) {
- let container,
- count = 0;
- do {
- container = await page.$(".recipeDetailContainer");
- if (!container) {
- await page.waitForTimeout(100);
- count++;
- }
- } while (!container && count < 60);
- return true;
+ return await page.waitForSelector('#schema', {
+ visible: true,
+ });
}
scrape($) {
- this.defaultSetDescription($);
- this.recipe.name = this.textTrim($("h1.title"));
-
- const jsonLD = $("script[type='application/ld+json']")[0];
- if (jsonLD && jsonLD.children && jsonLD.children[0].data) {
- const jsonRaw = jsonLD.children[0].data;
- const result = JSON.parse(jsonRaw);
-
- this.recipe.image = result.image[0] || '';
- this.recipe.tags = result.keywords ? result.keywords.split(',') : [];
-
- if (result.recipeCuisine) {
- this.recipe.tags.push(result.recipeCuisine)
- }
-
- if (result.recipeCategory) {
- this.recipe.tags.push(result.recipeCategory)
- }
-
- this.recipe.ingredients = result.recipeIngredient;
- this.recipe.instructions = result.recipeInstructions.map(step => step.text);
-
- this.recipe.time.prep = WoolworthsScraper.parsePTTime(result.prepTime);
- this.recipe.time.cook = WoolworthsScraper.parsePTTime(result.cookTime);
- this.recipe.time.total = WoolworthsScraper.parsePTTime(result.totalTime);
-
- this.recipe.servings = result.recipeYield;
-
- } else {
- // keep older code as fallback for required fields
- this.defaultSetImage($);
- const { ingredients, instructions } = this.recipe;
-
- $(".ingredient-list").each((i, el) => {
- ingredients.push(this.textTrim($(el)));
- });
-
- $(".step-content").each((i, el) => {
- let text = this.textTrim($(el));
- if (text.length) {
- instructions.push(text.replace(/^\d+\.\s/g, ""));
- }
- });
- }
+ this.defaultLD_JOSN($);
}
+
}
module.exports = WoolworthsScraper;
diff --git a/test/allRecipes.test.js b/test/allRecipes.test.js
index 8239b24..5e3ed07 100644
--- a/test/allRecipes.test.js
+++ b/test/allRecipes.test.js
@@ -48,14 +48,4 @@ describe("allRecipes", () => {
expect(error.message).to.equal("No recipe found on page");
}
});
-
- it("should throw an error if non-recipe page is used", async () => {
- try {
- allRecipes.url = constants.nonRecipeUrl;
- await allRecipes.fetchRecipe();
- assert.fail("was not supposed to succeed");
- } catch (error) {
- expect(error.message).to.equal("No recipe found on page");
- }
- });
});
diff --git a/test/constants/bonappetitConstants.js b/test/constants/bonappetitConstants.js
index 6cd9ec1..d26fcac 100644
--- a/test/constants/bonappetitConstants.js
+++ b/test/constants/bonappetitConstants.js
@@ -27,7 +27,6 @@ module.exports = {
"Add half of kale mixture to noodles and toss to incorporate. Drizzle in more dressing as needed, tossing until noodles are creamy; season with salt. Pile remaining kale on top. Drizzle with additional sesame oil and sprinkle with more red pepper flakes."
],
tags: [
- "recipes",
"soba",
"noodle",
"kale",
@@ -52,8 +51,8 @@ module.exports = {
ready: "",
total: ""
},
- servings: "4",
+ servings: "4 servings",
image:
- "https://assets.bonappetit.com/photos/5d4b5b3cecc81500091c6835/16:9/w_1280,c_limit/0919-Soba-Noodles.jpg"
+ "https://assets.bonappetit.com/photos/5d4b5b3cecc81500091c6835/5:7/w_2344,h_3282,c_limit/0919-Soba-Noodles.jpg"
}
};
diff --git a/test/constants/copykatConstants.js b/test/constants/copykatConstants.js
index 4f857da..36aafec 100644
--- a/test/constants/copykatConstants.js
+++ b/test/constants/copykatConstants.js
@@ -5,7 +5,7 @@ module.exports = {
nonRecipeUrl: "https://copykat.com/contact/",
expectedRecipe: {
name: "Air Fryer Croutons",
- description: "See how quick and easy it is to make buttery, crispy, homemade croutons in an air fryer with this easy, step-by-step recipe. Make tasty croutons in minutes!",
+ description: "See how quick and easy it is to make buttery, crispy, homemade croutons in an air fryer with this easy, step-by-step recipe. Tasty croutons in minutes!",
ingredients: [
"4 slices bread",
"2 tablespoons melted butter",
@@ -19,12 +19,12 @@ module.exports = {
],
tags: [],
time: {
- prep: "",
- cook: "",
+ prep: "5 minutes",
+ cook: "7 minutes",
active: "",
inactive: "",
ready: "",
- total: ""
+ total: "12 minutes"
},
servings: "4",
image:
diff --git a/test/constants/defaultLdJsonConstants.js b/test/constants/defaultLdJsonConstants.js
new file mode 100644
index 0000000..ed11de9
--- /dev/null
+++ b/test/constants/defaultLdJsonConstants.js
@@ -0,0 +1,1978 @@
+module.exports = {
+ tests: [
+ {
+ url: "https://therealfoodrds.com/veggie-loaded-turkey-chili/",
+ expected: {
+ "name": "Veggie Loaded Turkey Chili",
+ "description": "When the weather turns cold, warming up with a bowl of Veggie Loaded Turkey Chili is about as good as it gets!",
+ "image": "https://therealfooddietitians.com/wp-content/uploads/2017/10/IMG_9397-2-e1508438046925-225x225.jpg",
+ "ingredients": [
+ "1 lb. lean ground turkey, beef or chicken",
+ "1 Tbsp olive oil or avocado oil",
+ "2 large garlic cloves, minced",
+ "1/2 medium onion, diced",
+ "1 small red bell pepper, diced",
+ "1 small zucchini or yellow squash, diced",
+ "1 medium carrot, diced",
+ "2 Tbsp. chili powder",
+ "1 Tbsp. cumin, ground",
+ "1 can (15 ounces) tomato sauce + 1/2 can of water or broth",
+ "1 can (15 ounces) Crushed or petite diced tomatoes",
+ "1 can (15 ounces) black beans, rinsed and drained",
+ "1 cup corn, frozen",
+ "Dash of Cayenne (optional)",
+ "Salt and pepper, to taste",
+ "Optional: Diced avocado, chopped cilantro, shredded cheese, sour cream or Greek yogurt and/or lime wedges for serving",
+ ],
+ "instructions": [
+ "In a large pot or Dutch oven over medium heat add the oil. Once the oil is hot, add ground meat, garlic, onions, bell peppers, zucchini or yellow squash, and carrots and sauté for 7-9 minutes or until meat is cooked and no longer pink.",
+ "Add seasonings, tomato sauce, crushed tomatoes, beans, corn, and water. Bring to a boil over medium-high heat. Reduce heat to low, cover, and simmer for 15 minutes or until carrots are tender. Serve with toppings of choice.",
+ "Follow directions for the Stovetop version through Step 1.",
+ "Add turkey and vegetable mixture to slow cooker.",
+ "Add remaining ingredients (except salt and pepper) and stir to combine.",
+ "Cook on LOW for 8 hours or on HIGH for 4 hours.",
+ ],
+ "sectionedInstructions": [
+ {
+ "image": "",
+ "sectionTitle": "Stovetop Directions:",
+ "text": "In a large pot or Dutch oven over medium heat add the oil. Once the oil is hot, add ground meat, garlic, onions, bell peppers, zucchini or yellow squash, and carrots and sauté for 7-9 minutes or until meat is cooked and no longer pink.",
+ },
+ {
+ "image": "",
+ "sectionTitle": "Stovetop Directions:",
+ "text": "Add seasonings, tomato sauce, crushed tomatoes, beans, corn, and water. Bring to a boil over medium-high heat. Reduce heat to low, cover, and simmer for 15 minutes or until carrots are tender. Serve with toppings of choice.",
+ },
+ {
+ "image": "",
+ "sectionTitle": "Slow Cooker Directions:",
+ "text": "Follow directions for the Stovetop version through Step 1.",
+ },
+ {
+ "image": "",
+ "sectionTitle": "Slow Cooker Directions:",
+ "text": "Add turkey and vegetable mixture to slow cooker.",
+ },
+ {
+ "image": "",
+ "sectionTitle": "Slow Cooker Directions:",
+ "text": "Add remaining ingredients (except salt and pepper) and stir to combine.",
+ },
+ {
+ "image": "",
+ "sectionTitle": "Slow Cooker Directions:",
+ "text": "Cook on LOW for 8 hours or on HIGH for 4 hours.",
+ }
+ ],
+ "servings": "6",
+ "tags": [
+ "Entree | Soup",
+ ],
+ "time": {
+ "active": "",
+ "cook": "25 minutes",
+ "inactive": "",
+ "prep": "15 minutes",
+ "ready": "",
+ "total": "40 minutes"
+ }
+ }
+ },
+ {
+ url: "https://www.simplyrecipes.com/recipes/panzanella_bread_salad/",
+ expected: {
+ "name": "Panzanella Bread Salad",
+ "description": "Got ripe summer tomatoes? Got day-old bread? Make this classic Tuscan Panzanella Salad recipe! This is a great make-ahead recipe for a summer potluck or backyard party, or make it for dinner and serve with grilled chicken.",
+ "image": "https://www.simplyrecipes.com/thmb/t7sd-cTfzF4AKAmDZCbWPDCLpS0=/1600x900/smart/filters:no_upscale()/__opt__aboutcom__coeus__resources__content_migration__simply_recipes__uploads__2013__07__panzanella-bread-salad-horiz-a-1600-694a76c8b391430c8012f5c916aa8caa.jpg",
+ "ingredients": [
+ "4 cups tomatoes, cut into large chunks",
+ "4 cups day old (somewhat dry and hard) crusty bread (Italian or French loaf), cut into chunks the same size as the tomatoes (see Recipe Note)",
+ "1 cucumber, skinned and seeded, cut into large chunks",
+ "1/2 red onion, chopped",
+ "1 bunch fresh basil, torn into little pieces",
+ "1/4 to 1/2 cup high quality extra virgin olive oil",
+ "Salt and pepper to taste",
+ ],
+ "instructions": [
+ "Mix everything together and let marinate, covered, at room temperature for at least 30 minutes.",
+ "If refrigerating, let come to room temperature before serving.",
+ ],
+ "sectionedInstructions": [
+ {
+ "image": "",
+ "sectionTitle": "",
+ "text": "Mix everything together and let marinate, covered, at room temperature for at least 30 minutes.",
+ },
+ {
+ "image": "",
+ "sectionTitle": "",
+ "text": "If refrigerating, let come to room temperature before serving.",
+ }
+ ],
+ "servings": "8",
+ "tags": [
+ "Make-ahead",
+ "Salad",
+ "Italian",
+ "Vegan",
+ "Vegetarian",
+ "Lunch",
+ "Side Dish",
+ "Favorite Summer"
+ ],
+ "time": {
+ "active": "",
+ "cook": "",
+ "inactive": "",
+ "prep": "15 minutes",
+ "ready": "",
+ "total": "45 minutes"
+ }
+ }
+ },
+ {
+ url: "https://gimmedelicious.com/creamy-spinach-and-mushroom-pasta-bake",
+ expected: {
+ "name": "Creamy Spinach and Mushroom Pasta Bake",
+ "description": "Pasta with spinach & mushroom sautéed in butter and garlic then baked in parmesan cream sauce. This creamy pasta casserole is packed full of flavor and makes a delicious quick weeknight dinner!",
+ "image": "https://gimmedelicious.com/wp-content/uploads/2021/01/Spinach-Mushroom-Pasta-Bake.jpg",
+ "ingredients": [
+ "12 oz pasta (uncooked)",
+ "2 tablespoons unsalted butter",
+ "1 small onion (diced)",
+ "1 pound mushrooms of choice (thinly sliced)",
+ "2 cloves garlic (minced)",
+ "3 cups baby spinach",
+ "1 teaspoon italian seasoning",
+ "1/2 tsp salt",
+ "1/4 tsp pepper",
+ "1 tablespoon all-purpose flour",
+ "1/2 cup vegetable broth (or water)",
+ "1 cup light cream (or half and half)",
+ "1/4 cup freshly grated Parmesan",
+ "1 cup mozzarella cheese",
+ "2 tablespoons chopped fresh parsley leaves"
+ ],
+ "instructions": [
+ "Pre-heat oven to 375F.In a large pot of boiling salted water, cook pasta according to package instructions; drain well. Set aside.",
+ "Melt butter in a large skillet over medium heat. onion and mushrooms, cook for 2-3 minute or until the mushrooms are soft and tender. Add garlic, spinach, italian seasoning, and salt + pepper. cook for another minute.",
+ "Whisk in flour until lightly browned, about 1 minute. Gradually whisk in vegetable broth and then cream, and cook, whisking constantly, until incorporated, about 1-2 minutes. Stir in parmesan just before turning off heat.",
+ "Pour cooked pasta into a large 13x9 baking dish. Top with spinach mushroom cream sauce. Drizzle with mozzarella cheese. Bake for 18-20 minutes or until bubbly."
+ ],
+ "sectionedInstructions": [
+ {
+ "image": "",
+ "sectionTitle": "Pre-heat oven to 375F.In a large pot of boiling salted water, cook pasta according to package instructions; drain well. Set aside.",
+ "text": "Pre-heat oven to 375F.In a large pot of boiling salted water, cook pasta according to package instructions; drain well. Set aside."
+ },
+ {
+ "image": "",
+ "sectionTitle": "Melt butter in a large skillet over medium heat. onion and mushrooms, cook for 2-3 minute or until the mushrooms are soft and tender. Add garlic, spinach, italian seasoning, and salt + pepper. cook for another minute.",
+ "text": "Melt butter in a large skillet over medium heat. onion and mushrooms, cook for 2-3 minute or until the mushrooms are soft and tender. Add garlic, spinach, italian seasoning, and salt + pepper. cook for another minute."
+ },
+ {
+ "image": "",
+ "sectionTitle": "Whisk in flour until lightly browned, about 1 minute. Gradually whisk in vegetable broth and then cream, and cook, whisking constantly, until incorporated, about 1-2 minutes. Stir in parmesan just before turning off heat.",
+ "text": "Whisk in flour until lightly browned, about 1 minute. Gradually whisk in vegetable broth and then cream, and cook, whisking constantly, until incorporated, about 1-2 minutes. Stir in parmesan just before turning off heat."
+ },
+ {
+ "image": "",
+ "sectionTitle": "Pour cooked pasta into a large 13x9 baking dish. Top with spinach mushroom cream sauce. Drizzle with mozzarella cheese. Bake for 18-20 minutes or until bubbly.",
+ "text": "Pour cooked pasta into a large 13x9 baking dish. Top with spinach mushroom cream sauce. Drizzle with mozzarella cheese. Bake for 18-20 minutes or until bubbly."
+ }
+ ],
+ "servings": "6",
+ "tags": [
+ "baked",
+ "creamy",
+ "pasta",
+ "spinach mushroom",
+ "American",
+ "Dinner",
+ ],
+ "time": {
+ "active": "",
+ "cook": "25 minutes",
+ "inactive": "",
+ "prep": "5 minutes",
+ "ready": "",
+ "total": "30 minutes",
+ }
+ }
+ },
+ {
+ url: "https://www.epicurious.com/recipes/food/views/trout-toast-with-soft-scrambled-eggs",
+ expected: {
+ name: "Trout Toast with Soft Scrambled Eggs Recipe",
+ description: "Splurge on high-quality smoked fish and good bread—it makes all the difference",
+ ingredients: [
+ "8 large eggs",
+ "3/4 tsp. kosher salt, plus more",
+ "6 Tbsp. unsalted butter, divided",
+ '4 (1"-thick) slices sourdough or\tcountry-style bread',
+ "3 Tbsp. crème fraîche or sour cream",
+ '1 skin-on, boneless smoked trout fillet (about 5 oz.), skin removed, flesh broken into 1" pieces',
+ "1 lemon, halved",
+ "Freshly ground black pepper",
+ "2 scallions, thinly sliced on a diagonal",
+ "2 Tbsp. coarsely chopped dill",
+ "4 oz. mature arugula, tough stems trimmed (about 4 cups)",
+ "2 tsp. extra-virgin olive oil"
+ ],
+ instructions: [
+ "Crack eggs into a medium bowl and add 3/4 tsp. salt. Whisk until no streaks remain.",
+ "Heat 2 Tbsp. butter in a large nonstick skillet over medium. As soon as foaming subsides, add 2 slices of bread and cook until golden brown underneath, about 3 minutes. Transfer to plates, cooked side up. Repeat with another 2 Tbsp. butter and remaining 2 slices of bread. Season toast with salt. Wipe out skillet and let it cool 3 minutes.",
+ "Heat remaining 2 Tbsp. butter in reserved skillet over medium-low. Once butter is foaming, cook egg mixture, stirring with a heatproof rubber spatula in broad sweeping motions, until some curds begin to form but eggs are still runny, about 2 minutes. Stir in crème fraîche and cook, stirring occasionally, until eggs are barely set, about 1 minute.",
+ "Spoon eggs over toast and top with trout. Finely grate lemon zest from one of the lemon halves over trout, then squeeze juice over toast. Season with pepper; scatter scallions and dill on top.",
+ "Squeeze juice from remaining lemon half into a medium bowl. Add arugula and drizzle with oil; season with salt and pepper. Toss to coat. Mound alongside toasts."
+ ],
+ "sectionedInstructions": [
+ {
+ "image": "",
+ "sectionTitle": "",
+ "text": "Crack eggs into a medium bowl and add 3/4 tsp. salt. Whisk until no streaks remain."
+ },
+ {
+ "image": "",
+ "sectionTitle": "",
+ "text": "Heat 2 Tbsp. butter in a large nonstick skillet over medium. As soon as foaming subsides, add 2 slices of bread and cook until golden brown underneath, about 3 minutes. Transfer to plates, cooked side up. Repeat with another 2 Tbsp. butter and remaining 2 slices of bread. Season toast with salt. Wipe out skillet and let it cool 3 minutes."
+ },
+ {
+ "image": "",
+ "sectionTitle": "",
+ "text": "Heat remaining 2 Tbsp. butter in reserved skillet over medium-low. Once butter is foaming, cook egg mixture, stirring with a heatproof rubber spatula in broad sweeping motions, until some curds begin to form but eggs are still runny, about 2 minutes. Stir in crème fraîche and cook, stirring occasionally, until eggs are barely set, about 1 minute."
+ },
+ {
+ "image": "",
+ "sectionTitle": "",
+ "text": "Spoon eggs over toast and top with trout. Finely grate lemon zest from one of the lemon halves over trout, then squeeze juice over toast. Season with pepper; scatter scallions and dill on top."
+ },
+ {
+ "image": "",
+ "sectionTitle": "",
+ "text": "Squeeze juice from remaining lemon half into a medium bowl. Add arugula and drizzle with oil; season with salt and pepper. Toss to coat. Mound alongside toasts."
+ }
+ ],
+ tags: [
+ "bon appétit",
+ "breakfast",
+ "brunch",
+ "dinner",
+ "egg",
+ "fish",
+ "trout",
+ "peanut free",
+ "tree nut free",
+ "bread",
+ "sourdough",
+ "web"
+ ],
+ time: {
+ prep: "",
+ cook: "",
+ active: "",
+ inactive: "",
+ ready: "",
+ total: ""
+ },
+ servings: "4 servings",
+ image: "https://assets.epicurious.com/photos/5c1146171ba70e4fce83c3e5/2:1/w_4000,h_2000,c_limit/trout-toast-with-soft-scrambled-eggs-recipe-BA-121218.jpg"
+ }
+ },
+ {
+ url: "https://bakeplaysmile.com/favourite-chocolate-cake/#recipe",
+ expected: {
+ name: 'The BEST Chocolate Mud Cake',
+ description: 'You only need one chocolate mud cake recipe... and ' +
+ 'this is it! It really is the best chocolate mud ' +
+ 'cake recipe ever! Dense, rich and oh-so-delicious!',
+ ingredients: [
+ '1 3/4 cup (220g) plain flour',
+ '1 3/4 cup (350g) caster sugar',
+ '3/4 cup (65g) cocoa powder',
+ '1 tsp baking powder',
+ '2 tsps bi-carb soda',
+ '1 tsp salt',
+ '1 cup (250ml) buttermilk (see tips)',
+ '1/2 cup (125ml) vegetable oil',
+ '2 large eggs (at room temperature)',
+ '1 tsp vanilla extract',
+ '1 cup (250ml) coffee (hot and strong)',
+ '290 g unsalted butter (softened to room temperature)',
+ '3-4 cups (360-480g) icing sugar',
+ '3/4 cup (65g) cocoa powder',
+ '3-5 tbs (45-75ml) milk',
+ '1 tsp vanilla extract',
+ '1/4 tsp salt (optional)'
+ ],
+ instructions: [
+ 'Preheat oven to 170 degrees celsius.',
+ 'Grease two 9 inch round cake pans and line with baking paper.',
+ 'Sift the flour, sugar, cocoa powder, baking ' +
+ 'powder, bi-carb soda and salt into a bowl and set ' +
+ 'aside.',
+ 'Using beaters or a stand mixer, mix the buttermilk, ' +
+ 'oil, eggs and vanilla in a large bowl until well ' +
+ 'combined.',
+ 'Slowly add all of the dry ingredients to ' +
+ 'the wet ingredients with the mixer on low.',
+ 'Pour in the coffee and mix.',
+ 'Divide the batter equally between the baking pans and bake for ' +
+ 'approximately 25 minutes or until a toothpick inserted in the center ' +
+ "comes out clean (don't overcook the cake - you want it to be nice and " +
+ 'fudge-like!)',
+ 'Allow to cool completely.',
+ 'To make the frosting beat the butter on high speed until ' +
+ 'smooth and creamy (this will take a couple of minutes).',
+ 'Reduce the speed to low and slowly add in 3 1/2 ' +
+ 'cups of icing sugar as well as the cocoa powder.',
+ 'Beat until the icing sugar and cocoa have been completely ' +
+ 'mixed into the butter (again this will take a couple of ' +
+ 'minutes).',
+ 'Turn the mixer up to medium speed and add in the vanilla and the milk.',
+ 'Beat on high speed for 1 minute.',
+ "If your frosting isn't thick enough, feel free " +
+ 'to add in the remaining 1/2 cup of icing sugar.',
+ 'Add a tiny bit of salt to taste (optional).',
+ 'Spread a little frosting onto a serving ' +
+ 'cake plate (this will hold the cake in ' +
+ 'place).',
+ 'Carefully place one of the cakes on top of the ' +
+ 'icing (make sure the flat side is facing up).',
+ 'Using a spatula or flat knife, spread the top of the cake with frosting.',
+ 'Place the second cake on top (this time with the rounded side up) ' +
+ 'and spread the frosting evenly onto the top and the sides of the ' +
+ 'cake.',
+ 'Decorate with fresh strawberries or any preferred toppings.',
+ 'Store in an airtight container at room temperature for 3-4 days ' +
+ 'or in the fridge for 5-6 days. Please note that keeping the cake ' +
+ 'at room temperature will result in a beautiful, moist texture.',
+ 'Preheat oven to 170 degrees celsius (fan-forced). Grease ' +
+ 'two 9 inch round cake pans and line with baking paper.',
+ 'Measure the flour, sugar, cocoa powder, baking ' +
+ 'powder, bi-carb soda and salt into the TM bowl and ' +
+ 'sift for 5 seconds, Speed 8. Set aside in a separate ' +
+ 'bowl.',
+ 'Place the the buttermilk, oil, eggs and vanilla in the ' +
+ 'Thermomix bowl and mix on Speed 3 until well combined.',
+ 'With the blades on speed 2, slowly add the dry ' +
+ 'ingredients to the wet ingredients and mix until ' +
+ 'combined.',
+ 'Pour in the coffee and mix on Speed 2 until combined.',
+ 'Divide the batter equally between the baking pans and bake ' +
+ 'for approximately 25 minutes or until a toothpick inserted in ' +
+ "the center comes out clean (don't overcook the cake - you " +
+ 'want it to be nice and fudge-like!). Allow to cool ' +
+ 'completely.',
+ 'To make the frosting add the icing sugar to the Thermomix bowl and ' +
+ 'mix for 10 seconds, Speed 9, then add all of the remaining ' +
+ 'ingredients and mix for 30 seconds, Speed 4, or until light and ' +
+ 'fluffy.',
+ 'Spread a little frosting onto a serving cake plate (this ' +
+ 'will hold the cake in place). Carefully place one of the ' +
+ 'cakes on top of the icing (make sure the flat side is facing ' +
+ 'up).',
+ 'Using a spatula or flat knife, spread the top of the cake with ' +
+ 'frosting. Place the second cake on top (this time with the rounded ' +
+ 'side up) and spread the frosting evenly onto the top and the sides of ' +
+ 'the cake.',
+ 'Decorate with fresh strawberries or any preferred toppings.',
+ 'Store in an airtight container at room ' +
+ 'temperature for 3-4 days, or in the fridge for ' +
+ '5-6 days.'
+ ],
+ tags: ['chocolate mud cake', 'American', 'western', 'Cakes'],
+ time: {
+ prep: '30 minutes',
+ cook: '25 minutes',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '55 minutes'
+ },
+ servings: '16',
+ image: 'https://bakeplaysmile.com/wp-content/uploads/2020/10/Chocolate-Mud-Cake-7-2.jpg',
+ sectionedInstructions: [
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Preheat oven to 170 degrees celsius.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Grease two 9 inch round cake pans and line with baking paper.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Sift the flour, sugar, cocoa powder, baking ' +
+ 'powder, bi-carb soda and salt into a bowl and set ' +
+ 'aside.',
+ image: 'https://bakeplaysmile.com/wp-content/uploads/2020/10/Mud-Cake-Collages-2.jpg'
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Using beaters or a stand mixer, mix the buttermilk, ' +
+ 'oil, eggs and vanilla in a large bowl until well ' +
+ 'combined.',
+ image: 'https://bakeplaysmile.com/wp-content/uploads/2020/10/Mud-Cake-Collages-3.jpg'
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Slowly add all of the dry ingredients to ' +
+ 'the wet ingredients with the mixer on low.',
+ image: 'https://bakeplaysmile.com/wp-content/uploads/2020/10/Mud-Cake-Collages.jpg'
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Pour in the coffee and mix.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Divide the batter equally between the baking pans and ' +
+ 'bake for approximately 25 minutes or until a toothpick ' +
+ "inserted in the center comes out clean (don't overcook " +
+ 'the cake - you want it to be nice and fudge-like!)',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Allow to cool completely.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'To make the frosting beat the butter on high speed until ' +
+ 'smooth and creamy (this will take a couple of minutes).',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Reduce the speed to low and slowly add in 3 1/2 ' +
+ 'cups of icing sugar as well as the cocoa powder.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Beat until the icing sugar and cocoa have been completely ' +
+ 'mixed into the butter (again this will take a couple of ' +
+ 'minutes).',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Turn the mixer up to medium speed and add in the vanilla and the milk.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Beat on high speed for 1 minute.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: "If your frosting isn't thick enough, feel free " +
+ 'to add in the remaining 1/2 cup of icing sugar.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Add a tiny bit of salt to taste (optional).',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Spread a little frosting onto a serving ' +
+ 'cake plate (this will hold the cake in ' +
+ 'place).',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Carefully place one of the cakes on top of the ' +
+ 'icing (make sure the flat side is facing up).',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Using a spatula or flat knife, ' +
+ 'spread the top of the cake with ' +
+ 'frosting.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Place the second cake on top (this time with the rounded side up) ' +
+ 'and spread the frosting evenly onto the top and the sides of the ' +
+ 'cake.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Decorate with fresh strawberries or any preferred toppings.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Conventional Method',
+ text: 'Store in an airtight container at room temperature for 3-4 days ' +
+ 'or in the fridge for 5-6 days. Please note that keeping the cake ' +
+ 'at room temperature will result in a beautiful, moist texture.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'Preheat oven to 170 degrees celsius (fan-forced). Grease ' +
+ 'two 9 inch round cake pans and line with baking paper.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'Measure the flour, sugar, cocoa powder, baking ' +
+ 'powder, bi-carb soda and salt into the TM bowl and ' +
+ 'sift for 5 seconds, Speed 8. Set aside in a separate ' +
+ 'bowl.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'Place the the buttermilk, oil, eggs and vanilla in the ' +
+ 'Thermomix bowl and mix on Speed 3 until well combined.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'With the blades on speed 2, slowly add the dry ' +
+ 'ingredients to the wet ingredients and mix until ' +
+ 'combined.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'Pour in the coffee and mix on Speed 2 until combined.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'Divide the batter equally between the baking pans and bake ' +
+ 'for approximately 25 minutes or until a toothpick inserted in ' +
+ "the center comes out clean (don't overcook the cake - you " +
+ 'want it to be nice and fudge-like!). Allow to cool ' +
+ 'completely.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'To make the frosting add the icing sugar to the Thermomix bowl and ' +
+ 'mix for 10 seconds, Speed 9, then add all of the remaining ' +
+ 'ingredients and mix for 30 seconds, Speed 4, or until light and ' +
+ 'fluffy.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'Spread a little frosting onto a serving cake plate (this ' +
+ 'will hold the cake in place). Carefully place one of the ' +
+ 'cakes on top of the icing (make sure the flat side is facing ' +
+ 'up).',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'Using a spatula or flat knife, spread the top of the cake with ' +
+ 'frosting. Place the second cake on top (this time with the rounded ' +
+ 'side up) and spread the frosting evenly onto the top and the sides of ' +
+ 'the cake.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'Decorate with fresh strawberries or any preferred toppings.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Thermomix Method',
+ text: 'Store in an airtight container at room ' +
+ 'temperature for 3-4 days, or in the fridge for ' +
+ '5-6 days.',
+ image: ''
+ }
+ ]
+ }
+ },
+ {
+ url: "https://foody.co.il/foody_recipe/%d7%9e%d7%aa%d7%9b%d7%95%d7%9f-%d7%91-10-%d7%93%d7%a7%d7%95%d7%aa-%d7%a2%d7%95%d7%92%d7%aa-%d7%a9%d7%95%d7%a7%d7%95%d7%9c%d7%93-%d7%95%d7%a0%d7%a1-%d7%a7%d7%a4%d7%94-%d7%9e%d7%9e%d7%9b%d7%a8%d7%aa/",
+ expected: {
+ name: 'מתכון של עוגת שוקולד בחושה עם קפה ממכרת ב-10 דקות',
+ description: 'האורחים בדלת ואין לכם עוגה? עוגת שוקולד וקפה, כזו ' +
+ 'שילדים אוהבים ומבוגרים ממש לא אומרים לה לא. מתכון ' +
+ 'שמכינים ב-10 דקות, יש לה טעם מושקע בזכות הנס קפה ' +
+ 'שבתוכה',
+ ingredients: [
+ '1 כוס קמח תופח',
+ '1 כוס סוכר לבן',
+ '1 כוס שוקולית',
+ '1 כף קפה נמס',
+ '1 כוס שמן קנולה',
+ '4 ביצים L',
+ '125 מ"ל שמנת להקצפה יטבתה 38%',
+ '1 כפית תמצית וניל',
+ '1 כף קפה נמס',
+ '1/2 כוס מים רותחים',
+ '100 גרם שוקולד מריר',
+ '125 מ"ל שמנת להקצפה יטבתה 38%'
+ ],
+ instructions: [
+ 'אופן הכנה בקערה גדולה מערבבים את כל חומרי העוגה. מחממים תנור ל-180 מעלות. משמנים תבנית אפייה עגולה בקוטר 26 ס״מ או תבנית קוגלהוף (כמו בתמונה). שופכים את בלילת העוגה ואופים 30 דקות. כאשר העוגה יוצאת מהתנור שופכים עליה חצי כוס נס קפה שמכינים מכף קפה נמס וחצי כוס מים חמים). אם יש לכם מכונת קפה, מכינים אספרסו ושופכים, זה ממש משדרג את העוגה. מכינים את הציפוי: באמבט בן מרי ממיסים את השוקולד כאשר נמס מערבבים לתוכו את 1 2 השמנת שנותרה. שופכים על העוגה. אפשר לקשט את העוגה בסוכריות, אגוזים או פולי קפה טחונים.'
+ ],
+ tags: [
+ 'מכונת קפה סימנס',
+ 'עוגת שוקולד',
+ 'עוגת שוקולד עסיסית בטירוף',
+ 'שוקולד',
+ 'אוכל שילדים אוהבים'
+ ],
+ time: {
+ prep: '',
+ cook: '10 minutes',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '30 minutes'
+ },
+ servings: '1',
+ image: 'https://d3o5sihylz93ps.cloudfront.net/wp-content/uploads/2020/07/26170727/%D7%A2%D7%95%D7%92%D7%AA-%D7%A9%D7%95%D7%A7%D7%95%D7%9C%D7%93-%D7%95%D7%A0%D7%A1-%D7%A7%D7%A4%D7%94-%D7%9E%D7%94%D7%99%D7%A8%D7%94-355x236.jpg',
+ sectionedInstructions: []
+ }
+ },
+ {
+ url: "https://www.carine.co.il/foody_recipe/%d7%9b%d7%93%d7%95%d7%a8%d7%99-%d7%a9%d7%95%d7%a7%d7%95%d7%9c%d7%93-%d7%90%d7%95%d7%a8%d7%90%d7%95-%d7%9e%d7%93%d7%94%d7%99%d7%9e%d7%99%d7%9d-%d7%91%d7%a6%d7%99%d7%a7/",
+ expected: {
+ name: 'כדורי שוקולד אוראו מדהימים בצ’יק',
+ description: 'אחרי שתאכלו כדורי שוקולד אוראו, לא תוכלו לחזור לכדורי שוקולד רגילים! ' +
+ 'כדורי שוקולד משודרגים עם עוגיות אוראו וממרח בטעם אוראו שאי אפשר להפסיק ' +
+ 'לנשנש',
+ ingredients: [
+ '250 גרם עוגיות אוראו',
+ '1 מיכל שמנת מתוקה 38%',
+ '1 כוס ממרח בהשראת אוראו',
+ '1 חופן סוכריות צבעוניות'
+ ],
+ instructions: [
+ 'אופן הכנה מרסקים את עוגיות האוראו לפירורים (במערוך או מעבד מזון). מחממים ' +
+ 'את השמנת מתוקה לסף רתיחה (בסיר או במיקרוגל), מסירים מהאש ומעבירים לקערה. ' +
+ 'מערבבים פנימה את ממרח האוראו. מוסיפים את הפירורים ומערבבים היטב. מכסים ' +
+ 'בניילון נצמד ומעבירים למקרר להתייצבות למשך כשעתיים. מגלגלים בידיים ' +
+ 'רטובות לצורת כדורים. מניחים את הסוכריות הצבעוניות (או כל ציפוי אחר ' +
+ 'שאוהבים) בקערה, מכניסים את הכדורים ומגלגלים עד לכיסוי מלא ומניחים ' +
+ "במנג'טים.רוצים להכין את המתכון? כל מוצרי המזווה המתוק שבמתכון מחכים לכם " +
+ 'כאן! איזה כיף!'
+ ],
+ tags: [
+ 'המזווה המתוק',
+ 'מחית בהשראת אוראו וניל 500 גרם',
+ 'הילדים יעופו על זה!'
+ ],
+ time: {
+ prep: '',
+ cook: '20 minutes',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '2 hours 25 minutes'
+ },
+ servings: '20',
+ image: 'https://d3o5sihylz93ps.cloudfront.net/wp-content/uploads/sites/2/2021/03/24104713/IMG_0198-355x236.jpg',
+ sectionedInstructions: []
+ }
+ },
+ {
+ url: "https://www.hashulchan.co.il/%D7%9E%D7%AA%D7%9B%D7%95%D7%A0%D7%99%D7%9D/%d7%91%d7%99%d7%99%d7%92%d7%9c%d7%94-%d7%a9%d7%98%d7%95%d7%97%d7%99%d7%9d-%d7%91%d7%99%d7%aa%d7%99/",
+ expected: {
+ name: 'בייגלה שטוחים ביתי',
+ description: 'בייגלה בגרסה ביתית שלא תרצו להפסיק לאכול. הוא טעים ' +
+ 'בהרבה מהמתועש והכי חשוב - ההכנה עצמה היא הרפתקה שלמה',
+ ingredients: [
+ '15 גרם שמרים טריים (או 1 כפית שמרים יבשים)',
+ '180 מ"ל (3/4 כוס) מים',
+ '200 גרם (½1 כוסות + כף) קמח כוסמין מלא',
+ '35 מ"ל (2 כפות גדושות) שמן זית',
+ '1/2 כפית אבקת סודה לשתייה',
+ '1/2 כפית מלח',
+ '30 מ"ל (½1 כפות) סירופ מייפל ( טבעי ורצוי אורגני)',
+ '100 גרם שומשום מלא',
+ 'מלח ים אטלנטי'
+ ],
+ instructions: [
+ 'ממיסים שמרים במים, מוסיפים קמח, שמן זית, סודה ' +
+ 'לשתייה, מלח וסירופ מייפל ומערבבים 3-2 דקות לתערובת ' +
+ 'אחידה ורכה. מכסים את הקערה ומניחים בצד ל-15 דקות ' +
+ 'מנוחה.',
+ 'מחממים תנור ל-170 ומרפדים 3-2 תבניות בנייר אפייה.',
+ 'ממלאים שק זילוף עד חציו בתערובת, יוצרים חיתוך אלכסוני קטן בתחתית ' +
+ 'שק הזילוף (תתחילו בקטן - תמיד אפשר להרחיב9 מזלפים עיגולים עם חור ' +
+ 'במרכז לתוך התבניות, מפזרים מעל מלח ים ושומשום. מעבירים את התבניות ' +
+ 'לתנור ואופים 20-15 דקות עד שהבייגלה משחימים. מאחסנים בצנצנת אטומה.'
+ ],
+ tags: [
+ 'קל',
+ 'כשר',
+ 'אפייה',
+ 'חטיפים',
+ 'טבעוני',
+ 'מתכונים לילדים',
+ 'חטיפי בריאות',
+ 'אוכל בריא',
+ 'אוכל בריא לילדים',
+ 'במטבח עם הילדים',
+ 'אפייה טבעונית',
+ 'אפייה בלי חמאה'
+ ],
+ time: {
+ prep: '',
+ cook: '',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '40 minutes'
+ },
+ servings: '',
+ image: 'https://medias.hashulchan.co.il/www/uploads/2020/08/IMG_0254.jpg',
+ sectionedInstructions: []
+ }
+ },
+ {
+ url: "https://food.walla.co.il/item/3452312",
+ expected: {
+ name: 'מקלות גבינה מבצק עלים',
+ description: "פריכים, זהובים ומתובלים - כל מה שצריך בשביל מקלות הגבינה המופלאים האלו הם 4 מרכיבים. ויש גם טיפ איך תוכלו להכין אותם מראש ולשלוף בעת הצורך. למתכון המלא >>>",
+ ingredients: [
+ '1 חבילה בצק עלים שהופשר במקרר',
+ '200 גרם צדר מגוררת דק',
+ '100 גרם פרמזן מגוררת דק',
+ '1 ביצה טרופה',
+ 'מעט זעתר או תבלין פיצה'
+ ],
+ instructions: [
+ 'מחממים תנור ל-180 מעלות.',
+ 'מערבבים בקערה את שני סוגי הגבינות.',
+ 'פורסים את הבצק על משטח, מחלקים אותו לשני חלקים שווים ומרדדים מעט כל חלק.',
+ 'מברישים את אחת מיריעות הבצק בביצה טרופה, מפזרים כ-3/4 מכמות ' +
+ 'הגבינה ואת הזעתר או תבלין אחר שאוהבים ומניחים מעל את יריעת הבצק ' +
+ 'השניה.',
+ 'מרדדים יחד את שתי היריעות כדי להצמיד אותן היטב אחת לשניה. ' +
+ 'מברישים שוב בביצה טרופה ומפזרים את יתרת הגבינות והתבלין.',
+ 'בעזרת חותכן פיצה או סכין חדה, חותכים רצועות דקות ' +
+ 'לרוחב הבצק ברוחב של 3 סמ. מלפפים בזהירות כל רצועה ' +
+ 'לצורת בורג ומניחים על תבנית מרופדת נייר אפייה.',
+ 'אופים כ-25-30 דקות עד הזהבה.'
+ ],
+ tags: [
+ 'ישראלי',
+ 'צמחוני',
+ 'חלבי',
+ 'מאפים',
+ 'גבינה',
+ 'מתכוני ילדים',
+ 'כשר'
+ ],
+ time: {
+ prep: '10 minutes',
+ cook: '',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '30 minutes'
+ },
+ servings: '',
+ image: 'https://img.wcdn.co.il/f_auto,q_auto,w_1000,t_54/3/2/6/2/3262797-46.jpg',
+ sectionedInstructions: [
+ {
+ sectionTitle: 'שלב 1',
+ text: 'מחממים תנור ל-180 מעלות.',
+ image: ''
+ },
+ {
+ sectionTitle: 'שלב 2',
+ text: 'מערבבים בקערה את שני סוגי הגבינות.',
+ image: ''
+ },
+ {
+ sectionTitle: 'שלב 3',
+ text: 'פורסים את הבצק על משטח, מחלקים אותו ' +
+ 'לשני חלקים שווים ומרדדים מעט כל חלק.',
+ image: ''
+ },
+ {
+ sectionTitle: 'שלב 4',
+ text: 'מברישים את אחת מיריעות הבצק בביצה טרופה, מפזרים כ-3/4 מכמות ' +
+ 'הגבינה ואת הזעתר או תבלין אחר שאוהבים ומניחים מעל את יריעת הבצק ' +
+ 'השניה.',
+ image: ''
+ },
+ {
+ sectionTitle: 'שלב 5',
+ text: 'מרדדים יחד את שתי היריעות כדי להצמיד אותן היטב אחת לשניה. ' +
+ 'מברישים שוב בביצה טרופה ומפזרים את יתרת הגבינות והתבלין.',
+ image: ''
+ },
+ {
+ sectionTitle: 'שלב 6',
+ text: 'בעזרת חותכן פיצה או סכין חדה, חותכים רצועות דקות ' +
+ 'לרוחב הבצק ברוחב של 3 סמ. מלפפים בזהירות כל רצועה ' +
+ 'לצורת בורג ומניחים על תבנית מרופדת נייר אפייה.',
+ image: ''
+ },
+ {
+ sectionTitle: 'שלב 7',
+ text: 'אופים כ-25-30 דקות עד הזהבה.',
+ image: 'https://img.wcdn.co.il/f_auto,q_auto,w_1000,t_54/3/2/6/2/3262796-46.jpg'
+ }
+ ]
+ }
+ },
+ {
+ url: "https://www.chowhound.com/recipes/basic-pumpkin-pie-30175",
+ expected: {
+ name: 'Perfect Pumpkin Pie',
+ description: "For Chowhound's pumpkin pie recipe, you don't need to buy " +
+ 'a prepared crust or filling, just a single press-in ' +
+ 'crust. It only takes a few minutes to mix the ' +
+ 'ingredients...',
+ ingredients: [
+ '8 tablespoons unsalted butter (1 stick), melted and cooled slightly',
+ '1 tablespoon vegetable oil',
+ '1 tablespoon granulated sugar',
+ '1/4 teaspoon fine salt',
+ '1 1/3 cups all-purpose flour, plus more as needed',
+ '1 (15-ounce) can pumpkin purée (not pie mix)',
+ '1 (14-ounce) can sweetened condensed milk',
+ '2 large eggs',
+ '1 teaspoon ground cinnamon',
+ '1/2 teaspoon ground nutmeg',
+ '1/2 teaspoon fine salt',
+ '1/8 teaspoon ground cloves',
+ 'Easy Whipped Cream, for serving (recipe link in intro)'
+ ],
+ instructions: [
+ 'Stir the butter, oil, sugar, and salt together in a medium bowl until ' +
+ 'evenly combined. Add the measured flour and stir until a soft dough ' +
+ 'forms.',
+ 'Sprinkle the dough in small clumps over the bottom of a 9-1/2-inch ' +
+ 'deep-dish pie plate. Using a measuring cup or your fingers, evenly ' +
+ 'press the dough into the bottom and up the sides of the plate (flour ' +
+ 'the cup or your fingers occasionally to prevent sticking). Cover ' +
+ 'with plastic wrap and chill in the refrigerator for at least 30 ' +
+ 'minutes.',
+ 'Heat the oven to 350°F and arrange a rack in the lower third. ' +
+ 'Place a baking sheet on the rack while the oven is heating.',
+ 'Place all of the ingredients except the whipped cream in a large bowl ' +
+ 'and whisk until smooth and combined. Pour into the chilled pie crust.',
+ 'Place the pie on the hot baking sheet and bake until the ' +
+ 'top starts to brown and the filling is set but still ' +
+ 'jiggles slightly in the center, about 50 minutes. Remove ' +
+ 'from the oven to a wire rack and let cool completely ' +
+ 'before serving. Top slices of the pie with whipped cream, ' +
+ 'if desired.'
+ ],
+ tags: [
+ 'Christmas',
+ 'Thanksgiving',
+ 'Baking',
+ 'Dinner Party',
+ 'Potluck',
+ 'Vegetarian',
+ 'Condensed Milk',
+ 'Eggs',
+ 'Pumpkin Pie Spice Mix',
+ 'Pumpkin',
+ 'Pies',
+ 'Holidays',
+ 'Fall',
+ 'Winter',
+ 'Easy',
+ 'Eat: Bon Appétit!',
+ 'Comfort Food',
+ 'Dessert'
+ ],
+ time: {
+ prep: '0 hours 10 minutes',
+ cook: '',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '1 hours 30 minutes'
+ },
+ servings: '1 (9-1/2-inch) deep-dish pie, or 8 to 10 servings',
+ image: 'https://www.chowhound.com/a/recipe_photos/30175_easy_pumpkin_pie.jpg',
+ sectionedInstructions: [
+ {
+ sectionTitle: 'For the crust:',
+ text: 'Stir the butter, oil, sugar, and salt together ' +
+ 'in a medium bowl until evenly combined. Add the ' +
+ 'measured flour and stir until a soft dough ' +
+ 'forms.',
+ image: ''
+ },
+ {
+ sectionTitle: 'For the crust:',
+ text: 'Sprinkle the dough in small clumps over the bottom of a 9-1/2-inch ' +
+ 'deep-dish pie plate. Using a measuring cup or your fingers, evenly ' +
+ 'press the dough into the bottom and up the sides of the plate (flour ' +
+ 'the cup or your fingers occasionally to prevent sticking). Cover ' +
+ 'with plastic wrap and chill in the refrigerator for at least 30 ' +
+ 'minutes.',
+ image: ''
+ },
+ {
+ sectionTitle: 'For the pie:',
+ text: 'Heat the oven to 350°F and arrange a rack in the lower third. ' +
+ 'Place a baking sheet on the rack while the oven is heating.',
+ image: ''
+ },
+ {
+ sectionTitle: 'For the pie:',
+ text: 'Place all of the ingredients except the whipped cream in a large bowl ' +
+ 'and whisk until smooth and combined. Pour into the chilled pie crust.',
+ image: ''
+ },
+ {
+ sectionTitle: 'For the pie:',
+ text: 'Place the pie on the hot baking sheet and bake until the ' +
+ 'top starts to brown and the filling is set but still ' +
+ 'jiggles slightly in the center, about 50 minutes. Remove ' +
+ 'from the oven to a wire rack and let cool completely ' +
+ 'before serving. Top slices of the pie with whipped cream, ' +
+ 'if desired.',
+ image: ''
+ }
+ ]
+
+ }
+ },
+ {
+ url: "https://www.rachaelrayshow.com/recipes/roasted-eggplant-pasta-recipe-from-rachael-ray-pasta-alla-norma?",
+ expected: {
+ name: "John's Vegetarian Fave: Rach's Eggplant + Tomato Pasta alla Norma",
+ description: 'Rach shares her recipe for vegetarian Sicilian-style Pasta ' +
+ 'alla Norma—a.k.a. pasta with eggplant, tomatoes + basil.',
+ ingredients: [
+ '4 small to medium eggplant',
+ 'Salt',
+ 'Extra-virgin olive oil (EVOO) non-aerosol spray',
+ '3 Fresno chili peppers',
+ 'very thinly sliced',
+ '2 teaspoons sugar',
+ '1 teaspoon salt',
+ '3 tablespoons white wine vinegar',
+ '3 tablespoons extra-virgin olive oil (EVOO)',
+ '4 large cloves garlic',
+ 'thinly sliced',
+ '1 tablespoon Calabrian chili paste',
+ 'or 1 teaspoon red pepper flakes',
+ '2 pints cherry tomatoes',
+ 'halved (or two 14-ounce cans Italian cherry tomatoes)',
+ '¼ cup red vermouth',
+ 'Salt',
+ '2 tablespoons fresh oregano',
+ 'chopped (or 1½ teaspoons dried)',
+ 'One handful basil leaves',
+ 'torn',
+ '1 pound casarecce',
+ 'penne rigate or mezze rigatoni',
+ '12 ounces ricotta salata',
+ 'grated',
+ '½ cup finely chopped parsley and mint'
+ ],
+ instructions: [
+ 'For the eggplant, preheat oven to 425˚F with rack at ' +
+ 'center and line a baking sheet with foil and parchment ' +
+ 'paper',
+ 'Place a pot of water on to boil for pasta',
+ 'Thinly slice the eggplant into rounds and arrange on kitchen ' +
+ 'towels, then salt, drain 20 to 30 minutes, and press excess water ' +
+ 'out',
+ 'Arrange the eggplant on the parchment-lined sheet tray ' +
+ 'and spray on both sides lightly with oil, roast until ' +
+ 'browned and tender, about 15 minutes, then remove from ' +
+ 'oven',
+ 'For the pickled peppers, in a small bowl, dress sliced Fresno ' +
+ 'peppers with sugar, salt and vinegar, toss and let stand 20 to 30 ' +
+ 'minutes',
+ 'Meanwhile, for the tomato sauce, heat a deep skillet with a lid ' +
+ 'over medium to medium-high heat, add EVOO, 3 turns of the pan, add ' +
+ 'sliced garlic and stir 1 minute, add chili paste or flakes and ' +
+ 'stir, add tomatoes, vermouth (if using), salt, oregano, and basil, ' +
+ 'cover and slump tomatoes, 15 to 20 minutes, shaking pan ' +
+ 'occasionally',
+ 'For the pasta, salt boiling water and cook pasta 1 ' +
+ 'minute less than package directions for al dente',
+ 'Reserve ½ cup boiling water before draining, add pasta to ' +
+ 'sauce with ¾ roasted eggplant and some grated ricotta ' +
+ 'salata',
+ 'Add pasta water as needed to combine, transfer to ' +
+ 'serving bowl and top with more cheese, remaining ' +
+ 'eggplant, fresno chilis (if using), parsley and ' +
+ 'mint',
+ 'Listicle: Cucina Dinnerware 14-Inch Round Serving Bowl'
+ ],
+ tags: [
+ 'Food & Fun',
+ 'pasta',
+ 'vegetarian',
+ 'italian',
+ 'eggplant',
+ 'tomato'
+ ],
+ time: {
+ prep: '',
+ cook: '',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: ''
+ },
+ servings: '',
+ image: 'https://www.rachaelrayshow.com/sites/default/files/styles/1280x720/public/images/2021-06/pasta-alla-norma.jpg?h=d1cb525d&itok=4LETE94d',
+ sectionedInstructions: [
+ {
+ sectionTitle: '',
+ text: 'For the eggplant, preheat oven to 425˚F with rack at ' +
+ 'center and line a baking sheet with foil and parchment ' +
+ 'paper',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'Place a pot of water on to boil for pasta',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'Thinly slice the eggplant into rounds and arrange on kitchen ' +
+ 'towels, then salt, drain 20 to 30 minutes, and press excess water ' +
+ 'out',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'Arrange the eggplant on the parchment-lined sheet tray ' +
+ 'and spray on both sides lightly with oil, roast until ' +
+ 'browned and tender, about 15 minutes, then remove from ' +
+ 'oven',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'For the pickled peppers, in a small bowl, dress sliced Fresno ' +
+ 'peppers with sugar, salt and vinegar, toss and let stand 20 to 30 ' +
+ 'minutes',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'Meanwhile, for the tomato sauce, heat a deep skillet with a lid ' +
+ 'over medium to medium-high heat, add EVOO, 3 turns of the pan, add ' +
+ 'sliced garlic and stir 1 minute, add chili paste or flakes and ' +
+ 'stir, add tomatoes, vermouth (if using), salt, oregano, and basil, ' +
+ 'cover and slump tomatoes, 15 to 20 minutes, shaking pan ' +
+ 'occasionally',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'For the pasta, salt boiling water and cook pasta 1 ' +
+ 'minute less than package directions for al dente',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'Reserve ½ cup boiling water before draining, add pasta to ' +
+ 'sauce with ¾ roasted eggplant and some grated ricotta ' +
+ 'salata',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'Add pasta water as needed to combine, transfer to ' +
+ 'serving bowl and top with more cheese, remaining ' +
+ 'eggplant, fresno chilis (if using), parsley and ' +
+ 'mint',
+ image: ''
+ },
+ {
+ "image": "",
+ "sectionTitle": "",
+ "text": "Listicle: Cucina Dinnerware 14-Inch Round Serving Bowl"
+ }
+ ]
+ }
+ },
+ {
+ url: "https://www.delish.com/restaurants/a37070789/paris-hilton-vegan-burger-recipe/",
+ expected: {
+ name: "Paris Hilton's Vegan Un-Cheeseburger and Fries",
+ description: "Without any meat or cheese, Paris Hilton's recipe " +
+ "for a McDonald's burger is surprisingly delicious.",
+ ingredients: [
+ '2 (12-oz.) packages Impossible Meat',
+ '1 yellow onion, peeled and quartered',
+ '1 tsp. kosher salt',
+ 'Freshly ground black pepper',
+ 'Vegetable oil, for grill pan',
+ '4 buns, toasted',
+ 'Vegan cheese',
+ 'Tomatoes, sliced into rounds',
+ 'Lettuce',
+ 'Onion, sliced into rounds',
+ '1/2 c. vegan mayonnaise',
+ '1/2 c. vegan sour cream',
+ '1/4 c. relish',
+ '3 tbsp. ketchup',
+ '1/4 tsp. garlic powder',
+ '1 package frozen French fries'
+ ],
+ instructions: [
+ 'Make Pink Sauce: Whisk together ingredients and put in the refrigerator ' +
+ 'until ready to use. Make fries: Bake frozen French fries according to ' +
+ 'package directions. Make burger patties: Put onion into a small food ' +
+ 'processor and pulse until finely chopped. Add to a large bowl with ' +
+ 'Impossible Meat and salt and season with pepper. Mix until well ' +
+ 'combined. Form 1/2 cup of the "meat" mixture into balls and flatten ' +
+ 'into patties. Preheat grill pan over medium heat. Drizzle pan with a ' +
+ 'little oil and cook until well browned, about 3 minutes on each side. ' +
+ 'Spread Pink Sauce on buns, add patty, and top with cheese, lettuce, ' +
+ 'tomato, and onion.'
+ ],
+ tags: ['パン'],
+ time: {
+ prep: '0 seconds',
+ cook: '0 seconds',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '20 minutes'
+ },
+ servings: '4',
+ image: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/netflix-paris-social-copy-1627581598.jpg',
+ sectionedInstructions: []
+ }
+ },
+ {
+ url: "https://www.tablespoon.com/recipes/harry-potters-butterbeer/014213de-794b-4d49-a92d-64a07ffb2894",
+ expected: {
+ name: "Harry Potter's Butterbeer",
+ description: 'We put the mug in “muggle” this this delicious homemade ' +
+ 'butterbeer. A simple brown sugar and butter syrup gets topped ' +
+ 'with cream soda and a dollop of cream in this wildly popular ' +
+ 'drink. Next time you are having a Harry Potter movie marathon, ' +
+ 'book club meeting, or even a Halloween party, pull out all the ' +
+ 'stops with this sweet drink that even Harry, Ron, and Hermione ' +
+ 'would approve of.',
+ ingredients: [
+ '1 cup light or dark brown sugar',
+ '2 tablespoons water',
+ '6 tablespoons butter',
+ '1/2 teaspoon salt',
+ '1/2 teaspoon cider vinegar',
+ '3/4 cup heavy cream, divided',
+ '1/2 teaspoon rum extract',
+ '4 (12 oz) bottle cream soda'
+ ],
+ instructions: [
+ 'In a small saucepan over medium heat, combine the brown ' +
+ 'sugar and water. Bring to a gentle boil and cook, stirring ' +
+ 'often, until the mixture reads 240°F on a candy ' +
+ 'thermometer.',
+ 'Stir in the butter, salt, vinegar and 1/4 of the ' +
+ 'heavy cream. Set aside to cool to room ' +
+ 'temperature.',
+ 'Once the mixture has cooled, stir in the rum extract.',
+ 'In a medium bowl, combine 2 tablespoons of the brown sugar mixture and ' +
+ 'the remaining 1/2 cup of heavy cream. Use an electric mixer to beat ' +
+ 'until just thickened, but not completely whipped, about 2 to 3 ' +
+ 'minutes.',
+ 'To serve: divide the brown sugar mixture between 4 tall glasses ' +
+ '(about 1/4 cup for each glass). Add 1/4 cup of cream soda to each ' +
+ 'glass, then stir to combine. Fill each glass nearly to the top ' +
+ 'with additional cream soda, then spoon the whipped topping over ' +
+ 'each.'
+ ],
+ tags: ["harry potter's butterbeer", 'Beverage'],
+ time: {
+ prep: '0 hours 10 minutes',
+ cook: '',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '1 hours 0 minutes'
+ },
+ servings: '4',
+ image: 'https://images-gmi-pmc.edge-generalmills.com/1e592a2d-b8bf-4c92-b15f-b19e88b0f8c2.jpg',
+ sectionedInstructions: [
+ {
+ sectionTitle: '',
+ text: 'In a small saucepan over medium heat, combine the brown ' +
+ 'sugar and water. Bring to a gentle boil and cook, stirring ' +
+ 'often, until the mixture reads 240°F on a candy ' +
+ 'thermometer.',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'Stir in the butter, salt, vinegar and 1/4 of the ' +
+ 'heavy cream. Set aside to cool to room ' +
+ 'temperature.',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'Once the mixture has cooled, stir in the rum extract.',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'In a medium bowl, combine 2 tablespoons of the brown sugar mixture and ' +
+ 'the remaining 1/2 cup of heavy cream. Use an electric mixer to beat ' +
+ 'until just thickened, but not completely whipped, about 2 to 3 ' +
+ 'minutes.',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'To serve: divide the brown sugar mixture between 4 tall glasses ' +
+ '(about 1/4 cup for each glass). Add 1/4 cup of cream soda to each ' +
+ 'glass, then stir to combine. Fill each glass nearly to the top ' +
+ 'with additional cream soda, then spoon the whipped topping over ' +
+ 'each.',
+ image: ''
+ }
+ ]
+ }
+ },
+ {
+ url: "https://www.bettycrocker.com/recipes/oreo-shamrock-cupcakes/cfa5f2f3-f959-408a-907f-0429815cf8dc",
+ expected: {
+ name: 'Oreo-Shamrock Cupcakes',
+ description: 'These adorable cupcakes deliver on minty flavor ' +
+ 'and the lucky charm of delicious shamrock shakes.',
+ ingredients: [
+ '1 box Betty Crocker™ Super Moist™ Yellow Cake Mix',
+ 'Water, vegetable oil and eggs called for on cake mix box',
+ 'Mint green gel food color',
+ '2 1/2 cups Betty Crocker™ Whipped Fluffy ' +
+ 'White Frosting (from two 12-oz containers)',
+ '1 teaspoon peppermint extract',
+ '6 Oreo Thins chocolate mint crème ' +
+ 'sandwich cookies, cut into quarters (about ' +
+ '1 cup)'
+ ],
+ instructions: [
+ 'Heat oven to 350°F. Place paper baking ' +
+ 'cup in each of 24 regular-size muffin ' +
+ 'cups.',
+ 'Make cake batter as directed on box, stirring food color into batter to ' +
+ 'desired shade of green. Bake cupcakes as directed. Cool in pans 10 ' +
+ 'minutes; remove from pans to cooling rack. Cool completely, about 30 ' +
+ 'minutes.',
+ 'In medium bowl, mix frosting and peppermint extract. Spoon about ' +
+ '1 cup frosting into decorating bag fitted with 1/8- to 1/4-inch ' +
+ 'tip. Insert tip into center of 1 cupcake, about halfway down. ' +
+ 'Gently squeeze decorating bag, pulling upward until cupcake ' +
+ 'swells slightly and filling comes to top. Repeat with remaining ' +
+ 'cupcakes.',
+ 'Spoon remaining frosting into same bag; generously pipe ' +
+ 'frosting in circular motion on top of each cupcake, ' +
+ 'leaving 1/4-inch border around edge. Top with Oreo ' +
+ 'pieces.'
+ ],
+ tags: ['oreo-shamrock cupcakes', 'Dessert'],
+ time: {
+ prep: '0 hours 30 minutes',
+ cook: '',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '1 hours 30 minutes'
+ },
+ servings: '24',
+ image: 'https://images-gmi-pmc.edge-generalmills.com/9f46f888-5797-4c67-bce7-277d687f1196.jpg',
+ sectionedInstructions: [
+ {
+ sectionTitle: '',
+ text: 'Heat oven to 350°F. Place paper baking ' +
+ 'cup in each of 24 regular-size muffin ' +
+ 'cups.',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'Make cake batter as directed on box, stirring food ' +
+ 'color into batter to desired shade of green. Bake ' +
+ 'cupcakes as directed. Cool in pans 10 minutes; remove ' +
+ 'from pans to cooling rack. Cool completely, about 30 ' +
+ 'minutes.',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'In medium bowl, mix frosting and peppermint extract. Spoon about ' +
+ '1 cup frosting into decorating bag fitted with 1/8- to 1/4-inch ' +
+ 'tip. Insert tip into center of 1 cupcake, about halfway down. ' +
+ 'Gently squeeze decorating bag, pulling upward until cupcake ' +
+ 'swells slightly and filling comes to top. Repeat with remaining ' +
+ 'cupcakes.',
+ image: ''
+ },
+ {
+ sectionTitle: '',
+ text: 'Spoon remaining frosting into same bag; generously pipe ' +
+ 'frosting in circular motion on top of each cupcake, ' +
+ 'leaving 1/4-inch border around edge. Top with Oreo ' +
+ 'pieces.',
+ image: ''
+ }
+ ]
+ }
+ },
+ {
+ url: "https://www.vegrecipesofindia.com/pav-bhaji-recipe-mumbai-pav-bhaji-a-fastfood-recipe-from-mumbai/#wprm-recipe-container-136147",
+ expected: {
+ name: 'Pav Bhaji Recipe (Mumbai Pav Bhaji on Stovetop and Instant Pot)',
+ description: 'Pav Bhaji is a hearty, delightsome, flavorful meal of mashed ' +
+ 'vegetable gravy with fluffy soft buttery dinner rolls served with a ' +
+ 'side of crunchy piquant onions, tangy lemon and herby coriander. You ' +
+ 'will love this pav bhaji recipe for its Mumbai style flavors. I share ' +
+ 'the traditional method of making Pav Bhaji and a quick Instant Pot ' +
+ 'recipe.',
+ ingredients: [
+ '3 potatoes ((medium-sized) - 250 grams)',
+ '1 to 1.25 cups chopped cauliflower (- 120 to 130 grams)',
+ '1 cup chopped carrot',
+ '1 cup green peas (- fresh or frozen)',
+ '⅓ cup chopped french beans (- 12 to 14 french beans - optional)',
+ '2.25 to 2.5 cups water (- for pressure cooking veggies)',
+ '3 tablespoons Butter (- salted or unsalted)',
+ '1 teaspoon cumin seeds',
+ '½ cup finely chopped onion (or 1 medium to large onion)',
+ '2 teaspoons Ginger-Garlic Paste (or 1.5 inch ginger ' +
+ '& 5 to 6 medium garlic cloves crushed in a mortar)',
+ '1 teaspoon chopped green chilies (or ' +
+ 'serrano peppers or 1 to 2 green ' +
+ 'chilies)',
+ '½ cup finely chopped capsicum (or 1 ' +
+ 'medium sized capsicum (green bell ' +
+ 'pepper))',
+ '2 cups finely chopped tomatoes ((tightly ' +
+ 'packed) or about 2 to 3 large tomatoes)',
+ '1 teaspoon turmeric powder ((ground turmeric))',
+ '1 teaspoon kashmiri chilli powder (or freshly ' +
+ 'ground 3 to 4 soaked dry kashmiri red chilies)',
+ '2 to 3 tablespoons Pav Bhaji Masala (- add as required)',
+ '1.5 to 2 cups water (or the stock in ' +
+ 'which the veggies were cooked, add as ' +
+ 'needed)',
+ 'salt (as required)',
+ '2 to 3 tablespoons Butter ( - salted or unsalted)',
+ '½ teaspoon cumin seeds',
+ '½ cup finely chopped onions (or 1 ' +
+ 'medium to large onion - 50 to 60 ' +
+ 'grams)',
+ '2 teaspoons Ginger-Garlic Paste (or 1.5 inch ginger ' +
+ 'and 5 to 6 medium garlic cloves crushed in a mortar)',
+ '1 teaspoon chopped green chilies (or ' +
+ 'serrano peppers or 1 to 2 green ' +
+ 'chillies)',
+ '2 cups chopped tomatoes ( or 3 large tomatoes - 300 grams)',
+ '⅓ cup chopped capsicum ((green bell pepper))',
+ '2 cups chopped potatoes ( or 3 medium or 2 large potatoes - 250 grams)',
+ '¾ to 1 cup chopped cauliflower (- 100 grams)',
+ '¾ cup chopped carrots ( or 1 medium to large carrot - 100 grams)',
+ '¼ cup chopped french beans (- optional)',
+ '½ cup green peas (- fresh or frozen)',
+ '½ teaspoon turmeric powder',
+ '1 to 1.5 teaspoons kashmiri red chilli powder ' +
+ '(or ½ to 1 teaspoon cayenne pepper or paprika)',
+ '1.25 cups water',
+ 'salt (as required)',
+ '2 tablespoons Pav Bhaji Masala',
+ '1 to 2 tablespoons Butter (- to be added later)',
+ '2 tablespoons coriander leaves ((cilantro))',
+ '12 pav ((dinner rolls) or as required)',
+ '3 to 4 tablespoons Butter (- for roasting pav)',
+ '1 lemon (or lime, chopped in wedges)',
+ '1 onion (- medium to large, finely chopped)',
+ '3 to 4 tablespoons chopped coriander leaves (- for garnish)',
+ '2 to 3 tablespoons Butter (- for ' +
+ 'topping - add more for a richer ' +
+ 'version)'
+ ],
+ instructions: [
+ 'Rinse, peel and chop the veggies. You will need 1 cup chopped ' +
+ 'cauliflower, 1 cup chopped carrot, 3 medium sized potatoes (chopped) ' +
+ 'and ⅓ cup chopped french beans. You can also add veggies of your ' +
+ 'choice.',
+ 'Add all the above chopped veggies in a 2 litre ' +
+ 'pressure cooker. Also add 1 cup green peas (fresh or ' +
+ 'frozen).',
+ 'Add 2.25 to 2.5 cups water.',
+ 'Pressure cook the veggies for 5 to 6 ' +
+ 'whistles or for about 12 minutes on medium ' +
+ 'flame.',
+ 'When the pressure settles down on its own, open the cooker and ' +
+ 'check if the veggies are cooked well. You can even steam or cook ' +
+ 'the veggies in a pan. The vegetables have be to cooked ' +
+ 'completely.',
+ 'Heat a pan or kadai. You can also use a large tawa. Add ' +
+ '2 to 3 tablespoons butter. You can use amul butter or ' +
+ 'any brand of butter. Butter can be salted or unsalted.',
+ 'As soon as the butter melts, add 1 teaspoon cumin seeds.',
+ 'Let the cumin seeds crackle and change their color.',
+ 'Then add ½ cup finely chopped onions.',
+ 'Mix onions with the butter and saute on a low ' +
+ 'to medium flame till the onions translucent.',
+ 'Then add 2 teaspoons ginger-garlic paste. You can also crush 1.5 ' +
+ 'inch ginger and 5 to 6 medium garlic cloves in a mortar-pestle.',
+ 'Mix and saute till the raw aroma of both ginger and garlic goes away.',
+ 'Then add chopped green chilies. Mix well.',
+ 'Now add 2 cups finely chopped tomatoes. Mix very well.',
+ 'Then begin to sauté tomatoes on a low to medium heat.',
+ 'Saute till the tomatoes become soft and mushy and you see ' +
+ 'butter releasing from the sides. This takes about 6 to 7 ' +
+ 'minutes on a low to medium flame. If the tomatoes start ' +
+ 'sticking to the pan, then sprinkle some water and mix ' +
+ 'well.',
+ 'When the tomatoes have softened, then add ½ cup finely chopped ' +
+ 'capsicum (green bell pepper). Sauté for 2 to 3 minutes. If the ' +
+ 'mixture starts sticking to the pan, then you can sprinkle some water. ' +
+ 'You don’t need to cook the capsicum till very soft. A little crunch ' +
+ 'is alright.',
+ 'Add 1 teaspoon turmeric powder and 1 ' +
+ 'teaspoon kashmiri red chilli powder.',
+ 'Then add 2 to 3 tablespoons pav bhaji masala. mix very well.',
+ 'Add the cooked veggies. Add all of the stock or water from the ' +
+ 'pressure cooker in which the veggies were cooked. Mix very well.',
+ 'Then season with salt as per taste.',
+ 'With a potato masher, begin to mash the veggies directly in the pan.',
+ 'You can mash the veggies less or more according to the consistency you ' +
+ 'want. For a smooth mixture mash more. For a chunky pav bhaji, mash less.',
+ 'Keep on stirring occasionally and let ' +
+ 'the bhaji simmer for 8 to 10 minutes.',
+ 'If the bhaji looks dry and then add some more ' +
+ 'water. The consistency is neither very thick nor ' +
+ 'thin.',
+ 'Do stir often so that the bhaji does not stick to the pan. When ' +
+ 'the pav bhaji simmers to the desired consistency, check the taste. ' +
+ 'Add salt, pav bhaji masala, red chili powder or butter if ' +
+ 'required.',
+ 'When the bhaji is simmering, you can fry the pav so ' +
+ 'that you serve the pav with hot bhaji. Slice the ' +
+ 'pavs.',
+ 'Switch on the instant pot. Press the sauté button on ' +
+ 'less mode. Add 2 tablespoons butter in the ip steel ' +
+ 'insert.',
+ 'When the butter melts, add cumin seeds and let them splutter and change ' +
+ 'color. Then add finely chopped onions and sauté onions till they soften.',
+ 'Next add the ginger-garlic paste and green chillies. Mix and sauté ' +
+ 'for a few seconds till the raw aroma of ginger-garlic goes away.',
+ 'Then add chopped tomatoes and chopped capsicum. Sauté ' +
+ 'for 1 to 2 minutes.Add the chopped veggies and green ' +
+ 'peas.',
+ 'Add ½ teaspoon turmeric powder and 1 to 1.5 teaspoons kashmiri ' +
+ 'red chilli powder. If using any other red chili powder or cayenne ' +
+ 'pepper, then you can add less of it. Also, add salt as per taste.',
+ 'Mix everything very well. Add water and stir.',
+ 'Press the cancel button. Now press the pressure ' +
+ 'cooker/manual button and set time to 7 minutes on high ' +
+ 'pressure.',
+ 'When the beep sound is heard and the pressure ' +
+ 'cooking is complete, do a quick pressure release ' +
+ '(qpr). When all the pressure is released, open the ' +
+ 'lid.',
+ 'Using a napkin or oven mittens, remove the steel insert ' +
+ 'from the instant pot. Place it on your kitchen counter.',
+ 'With a potato masher, begin to mash the cooked ' +
+ 'vegetables. Mash very well. You can even use an ' +
+ 'immersion blender and puree the veggies. Just make a ' +
+ 'semi-fine puree.',
+ 'Now add 2 tablespoons pav bhaji masala and 1 to 2 tablespoons ' +
+ 'butter. You can skip the butter if you want. Mix very well.',
+ 'Place the steel insert pan in the IP. Press the ' +
+ 'cancel button and then press the sauté button on ' +
+ 'normal mode. Set the timer to 3 to 5 minutes or ' +
+ 'more.',
+ 'Simmer the bhaji for a few minutes, till it thickens a bit and you ' +
+ 'get the desired consistency. Stir often, so that the bhaji does not ' +
+ 'stick to the bottom. If the bhaji looks very thick, then add some ' +
+ 'water.',
+ 'Sprinkle 2 tablespoons chopped coriander leaves. Mix very well. Do ' +
+ 'check the taste and add salt, butter, kashmiri red chili powder or ' +
+ 'pav bhaji masala if required. Cancel and keep the IP on warm mode.',
+ 'Heat a skillet or a shallow frying pan. ' +
+ 'Keep the flame to a low and then add ' +
+ 'butter.',
+ 'When the butter begins to melt, add a bit of pav ' +
+ 'bhaji masala. You can skip pav bhaji masala if you ' +
+ 'want.',
+ 'Mix the pav bhaji masala very well with a spoon or spatula.',
+ 'Then place the pav on the butter.',
+ 'Rotate the pav all over the melted ' +
+ 'butter so that the pav absorbs the ' +
+ 'butter.',
+ 'Now turn over the pav and rotate them on the tawa so that the ' +
+ 'second side absorbs the butter. Add more butter if required.',
+ 'You can turn over and toast them more if ' +
+ 'required. Then remove in a plate and keep ' +
+ 'aside.',
+ 'Take the bhaji in a serving plate or a bowl. Top it up with one ' +
+ 'to two cubes of butter. You can add more butter, if you like.',
+ 'Place a side of finely chopped onions, lemon wedges and ' +
+ 'finely chopped coriander leaves. Or you can sprinkle ' +
+ 'onions, coriander leaves and lemon juice directly on the ' +
+ 'bhaji.',
+ 'Serve bhaji with the lightly pan fried and buttered pav. Pav ' +
+ 'bhaji is topped with chopped onions, coriander leaves and the ' +
+ 'lime or lemon juice is squeezed on the bhaji while eating.',
+ 'Refrigerate only the bhaji (vegetable gravy without any toppings of ' +
+ 'onions, coriander and lemon juice) in the refrigerator for 1 to 2 ' +
+ 'days.',
+ 'Reheat in a small pan. If the bhaji looks thick, ' +
+ 'mix in some water to loosen it a bit and reheat.'
+ ],
+ tags: [
+ 'pav bhaji',
+ 'Indian Street Food',
+ 'Maharashtrian',
+ 'Brunch',
+ 'Main Course',
+ 'Snacks',
+ 'Starters'
+ ],
+ time: {
+ prep: '20 minutes',
+ cook: '20 minutes',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '40 minutes'
+ },
+ servings: '5',
+ image: 'https://www.vegrecipesofindia.com/wp-content/uploads/2021/04/pav-bhaji-recipe-3.jpg',
+ sectionedInstructions: [
+ {
+ sectionTitle: 'Cooking veggies',
+ text: 'Rinse, peel and chop the veggies. You will need 1 cup chopped ' +
+ 'cauliflower, 1 cup chopped carrot, 3 medium sized potatoes (chopped) ' +
+ 'and ⅓ cup chopped french beans. You can also add veggies of your ' +
+ 'choice.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Cooking veggies',
+ text: 'Add all the above chopped veggies in a 2 litre ' +
+ 'pressure cooker. Also add 1 cup green peas (fresh or ' +
+ 'frozen).',
+ image: ''
+ },
+ {
+ sectionTitle: 'Cooking veggies',
+ text: 'Add 2.25 to 2.5 cups water.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Cooking veggies',
+ text: 'Pressure cook the veggies for 5 to 6 ' +
+ 'whistles or for about 12 minutes on medium ' +
+ 'flame.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Cooking veggies',
+ text: 'When the pressure settles down on its own, open the cooker and ' +
+ 'check if the veggies are cooked well. You can even steam or cook ' +
+ 'the veggies in a pan. The vegetables have be to cooked ' +
+ 'completely.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing onions',
+ text: 'Heat a pan or kadai. You can also use a large tawa. Add ' +
+ '2 to 3 tablespoons butter. You can use amul butter or ' +
+ 'any brand of butter. Butter can be salted or unsalted.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing onions',
+ text: 'As soon as the butter melts, add 1 teaspoon cumin seeds.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing onions',
+ text: 'Let the cumin seeds crackle and change their color.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing onions',
+ text: 'Then add ½ cup finely chopped onions.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing onions',
+ text: 'Mix onions with the butter and saute on a low ' +
+ 'to medium flame till the onions translucent.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing onions',
+ text: 'Then add 2 teaspoons ginger-garlic paste. You can also crush 1.5 ' +
+ 'inch ginger and 5 to 6 medium garlic cloves in a mortar-pestle.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing onions',
+ text: 'Mix and saute till the raw aroma of both ginger and garlic goes away.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing onions',
+ text: 'Then add chopped green chilies. Mix well.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing tomatoes',
+ text: 'Now add 2 cups finely chopped tomatoes. Mix very well.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing tomatoes',
+ text: 'Then begin to sauté tomatoes on a low to medium heat.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing tomatoes',
+ text: 'Saute till the tomatoes become soft and mushy and you see ' +
+ 'butter releasing from the sides. This takes about 6 to 7 ' +
+ 'minutes on a low to medium flame. If the tomatoes start ' +
+ 'sticking to the pan, then sprinkle some water and mix ' +
+ 'well.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing tomatoes',
+ text: 'When the tomatoes have softened, then add ½ cup finely chopped ' +
+ 'capsicum (green bell pepper). Sauté for 2 to 3 minutes. If the ' +
+ 'mixture starts sticking to the pan, then you can sprinkle some water. ' +
+ 'You don’t need to cook the capsicum till very soft. A little crunch ' +
+ 'is alright.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing ground spices',
+ text: 'Add 1 teaspoon turmeric powder and 1 ' +
+ 'teaspoon kashmiri red chilli powder.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Sautéing ground spices',
+ text: 'Then add 2 to 3 tablespoons pav bhaji masala. mix very well.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Adding cooked vegetables',
+ text: 'Add the cooked veggies. Add all of the stock or water from the ' +
+ 'pressure cooker in which the veggies were cooked. Mix very well.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Adding cooked vegetables',
+ text: 'Then season with salt as per taste.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Adding cooked vegetables',
+ text: 'With a potato masher, begin to mash the veggies directly in the pan.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Adding cooked vegetables',
+ text: 'You can mash the veggies less or more according ' +
+ 'to the consistency you want. For a smooth ' +
+ 'mixture mash more. For a chunky pav bhaji, mash ' +
+ 'less.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Adding cooked vegetables',
+ text: 'Keep on stirring occasionally and let ' +
+ 'the bhaji simmer for 8 to 10 minutes.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Adding cooked vegetables',
+ text: 'If the bhaji looks dry and then add some more ' +
+ 'water. The consistency is neither very thick nor ' +
+ 'thin.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Adding cooked vegetables',
+ text: 'Do stir often so that the bhaji does not stick to the pan. When ' +
+ 'the pav bhaji simmers to the desired consistency, check the taste. ' +
+ 'Add salt, pav bhaji masala, red chili powder or butter if ' +
+ 'required.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Adding cooked vegetables',
+ text: 'When the bhaji is simmering, you can fry the pav so ' +
+ 'that you serve the pav with hot bhaji. Slice the ' +
+ 'pavs.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Switch on the instant pot. Press the sauté button on ' +
+ 'less mode. Add 2 tablespoons butter in the ip steel ' +
+ 'insert.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'When the butter melts, add cumin seeds and let ' +
+ 'them splutter and change color. Then add finely ' +
+ 'chopped onions and sauté onions till they ' +
+ 'soften.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Next add the ginger-garlic paste and green chillies. Mix and sauté ' +
+ 'for a few seconds till the raw aroma of ginger-garlic goes away.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Then add chopped tomatoes and chopped capsicum. Sauté ' +
+ 'for 1 to 2 minutes.Add the chopped veggies and green ' +
+ 'peas.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Add ½ teaspoon turmeric powder and 1 to 1.5 teaspoons kashmiri ' +
+ 'red chilli powder. If using any other red chili powder or cayenne ' +
+ 'pepper, then you can add less of it. Also, add salt as per taste.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Mix everything very well. Add water and stir.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Press the cancel button. Now press the pressure ' +
+ 'cooker/manual button and set time to 7 minutes on high ' +
+ 'pressure.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'When the beep sound is heard and the pressure ' +
+ 'cooking is complete, do a quick pressure release ' +
+ '(qpr). When all the pressure is released, open the ' +
+ 'lid.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Using a napkin or oven mittens, remove the steel insert ' +
+ 'from the instant pot. Place it on your kitchen counter.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'With a potato masher, begin to mash the cooked ' +
+ 'vegetables. Mash very well. You can even use an ' +
+ 'immersion blender and puree the veggies. Just make a ' +
+ 'semi-fine puree.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Now add 2 tablespoons pav bhaji masala and 1 to 2 tablespoons ' +
+ 'butter. You can skip the butter if you want. Mix very well.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Place the steel insert pan in the IP. Press the ' +
+ 'cancel button and then press the sauté button on ' +
+ 'normal mode. Set the timer to 3 to 5 minutes or ' +
+ 'more.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Simmer the bhaji for a few minutes, till it thickens a bit and you ' +
+ 'get the desired consistency. Stir often, so that the bhaji does not ' +
+ 'stick to the bottom. If the bhaji looks very thick, then add some ' +
+ 'water.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Making Instant Pot Pav Bhaji',
+ text: 'Sprinkle 2 tablespoons chopped coriander leaves. Mix very well. Do ' +
+ 'check the taste and add salt, butter, kashmiri red chili powder or ' +
+ 'pav bhaji masala if required. Cancel and keep the IP on warm mode.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Toasting pav (dinner rolls)',
+ text: 'Heat a skillet or a shallow frying pan. ' +
+ 'Keep the flame to a low and then add ' +
+ 'butter.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Toasting pav (dinner rolls)',
+ text: 'When the butter begins to melt, add a bit of pav ' +
+ 'bhaji masala. You can skip pav bhaji masala if you ' +
+ 'want.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Toasting pav (dinner rolls)',
+ text: 'Mix the pav bhaji masala very well with a spoon or spatula.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Toasting pav (dinner rolls)',
+ text: 'Then place the pav on the butter.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Toasting pav (dinner rolls)',
+ text: 'Rotate the pav all over the melted ' +
+ 'butter so that the pav absorbs the ' +
+ 'butter.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Toasting pav (dinner rolls)',
+ text: 'Now turn over the pav and rotate them on the tawa so that the ' +
+ 'second side absorbs the butter. Add more butter if required.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Toasting pav (dinner rolls)',
+ text: 'You can turn over and toast them more if ' +
+ 'required. Then remove in a plate and keep ' +
+ 'aside.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Serving suggestions',
+ text: 'Take the bhaji in a serving plate or a bowl. Top it up with one ' +
+ 'to two cubes of butter. You can add more butter, if you like.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Serving suggestions',
+ text: 'Place a side of finely chopped onions, lemon wedges and ' +
+ 'finely chopped coriander leaves. Or you can sprinkle ' +
+ 'onions, coriander leaves and lemon juice directly on the ' +
+ 'bhaji.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Serving suggestions',
+ text: 'Serve bhaji with the lightly pan fried and buttered pav. Pav ' +
+ 'bhaji is topped with chopped onions, coriander leaves and the ' +
+ 'lime or lemon juice is squeezed on the bhaji while eating.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Storage and Leftovers',
+ text: 'Refrigerate only the bhaji (vegetable gravy without any toppings of ' +
+ 'onions, coriander and lemon juice) in the refrigerator for 1 to 2 ' +
+ 'days.',
+ image: ''
+ },
+ {
+ sectionTitle: 'Storage and Leftovers',
+ text: 'Reheat in a small pan. If the bhaji looks thick, ' +
+ 'mix in some water to loosen it a bit and reheat.',
+ image: ''
+ }
+ ]
+ }
+ }
+ ],
+ toBeFixed: [
+ {
+ url: "https://www.foodsdictionary.co.il/Recipes/5021",
+ expected: {
+ name: 'מוקפץ סיני עם חזה עוף וירקות',
+ description: 'חזה עוף מוקפץ עם מגוון ירקות בסגנון סיני ברוטב סויה וצ`ילי',
+ ingredients: [
+ 'חזה עוף מבושל-מטוגן',
+ 'שמן קנולה מזוכך',
+ 'פטריות מבושלות',
+ 'בצל מבושל',
+ 'פלפל אדום מבושל',
+ 'בצל ירוק',
+ 'פלפל ירוק חריף',
+ 'גזר מבושל',
+ 'קישוא %28חורף%29 מבושל',
+ 'כרוב מבושל',
+ 'שמן קנולה מזוכך',
+ 'רוטב סויה קיקומן דל נתרן',
+ 'רוטב צ%60ילי מתוק',
+ 'פלפל שחור',
+ 'מלח שולחן',
+ 'סוכר חום',
+ 'שומשום'
+ ],
+ instructions: [
+ '1. במחבת גדולה ומוצקה לטגן את רצועות חזה העוף עד להזהבה קלה.2. כשרצועות ' +
+ 'העוף מוכנות להוציאן להצטננות.3. באותה מחבת לחמם 3 כפות שמן נוספות ולטגן ' +
+ 'את הירקות לפי רמת הקושי - תחילה בצל עד להזהבה ולאחר מכן אפשר להוסיף את ' +
+ 'כל הירקות. שימו לב - הירקות צריכים להיות קריספיים ולא רכים.4. לאחר הקפצת ' +
+ 'הירקות יש להוסיף את חזה העוף המוכן ואת שאר התבלינים.5. להחזיר לאש לעוד 4 ' +
+ 'דקות בישול, לפזר מלמעלה את השומשום הקלוי ולערבב קלות.6. בתיאבון (:'
+ ],
+ tags: ['סיני', 'ירקות, עוף'],
+ time: {
+ prep: '',
+ cook: '',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '15 minutes'
+ },
+ servings: '5 מנות',
+ image: 'https://st1.foodsd.co.il/Images/Recipes/xxl/Recipe-5021-eOWGFcW189fiNAnM.jpg',
+ sectionedInstructions: []
+ }
+ },
+ ],
+ noLdJsonSupportedRecipeUrl: "https://rotteml.com/%D7%A4%D7%91%D7%9C%D7%95%D7%91%D7%94-%D7%A4%D7%99%D7%A8%D7%95%D7%AA-%D7%94%D7%93%D7%A8",
+ expectedPageInfo: {
+ "description": "פבלובה חורפית עם פירות הדר זה ליגה! כשהגשתי לשולחן את הפבלובה, התשואות היו ליגה!!! עכשיו, גם לכם יש את המתכון, היכנסו ותתחילו להכין.",
+ "image": "https://rotteml.com/wp-content/uploads/2021/12/WhatsApp-Image-2021-12-07-at-11.41.54.jpeg",
+ "ingredients": [],
+ "instructions": [],
+ "name": "פבלובה פירות הדר",
+ "servings": "",
+ "tags": [],
+ "time": {
+ "active": "",
+ "cook": "",
+ "inactive": "",
+ "prep": "",
+ "ready": "",
+ "total": ""
+ }
+ }
+}
diff --git a/test/constants/eatingwellConstants.js b/test/constants/eatingwellConstants.js
index 9b2158d..07d2ca5 100644
--- a/test/constants/eatingwellConstants.js
+++ b/test/constants/eatingwellConstants.js
@@ -1,61 +1,22 @@
module.exports = {
- testUrl:
- "http://www.eatingwell.com/recipe/264666/pressure-cooker-chicken-enchilada-soup/",
- testUrl2:
- "http://www.eatingwell.com/recipe/251433/mexican-pasta-salad-with-creamy-avocado-dressing/",
+ testUrl: "http://www.eatingwell.com/recipe/264666/pressure-cooker-chicken-enchilada-soup/",
+ testUrl2: "http://www.eatingwell.com/recipe/251433/mexican-pasta-salad-with-creamy-avocado-dressing/",
invalidUrl: "http://www.eatingwell.com/recipe/notarealurl",
invalidDomainUrl: "www.invalid.com",
- nonRecipeUrl:
- "http://www.eatingwell.com/recipes/18306/cooking-methods-styles/quick-easy/dessert/",
+ nonRecipeUrl: "http://www.eatingwell.com/recipes/18306/cooking-methods-styles/quick-easy/dessert/",
expectedRecipe: {
- name: "Pressure-Cooker Chicken Enchilada Soup",
- description:
- "This easy soup flavored with chili powder and a splash of lime is quick enough to prepare for a warming weeknight meal thanks to an electric pressure cooker like the Instant Pot. Lean chicken breast is easy to prep, but boneless, skinless chicken thighs would make a great substitute.",
- ingredients: [
- "1 tablespoon olive oil",
- "1 medium onion, chopped",
- "1 poblano pepper, seeded and chopped",
- "1 pound boneless, skinless chicken breast, cut into 1/2-inch pieces",
- "3 cloves garlic, minced",
- "2 tablespoons chili powder",
- "1 teaspoon salt",
- "4 cups low-sodium chicken broth",
- "1 (15 ounce) can low-sodium black beans, rinsed",
- "1 (14 ounce) can no-salt-added fire-roasted diced tomatoes",
- "Juice of 1 lime",
- "½ cup chopped fresh cilantro, plus more for garnish",
- "¾ cup shredded Mexican-style cheese blend",
- "Tortilla chips for garnish"
- ],
- instructions: [
- "Heat oil on high heat using the sauté function of your multicooker. (No sauté mode? See Tip.) Add onion, poblano, chicken, garlic, chili powder and salt. Cook, stirring occasionally, until the vegetables have softened and the chicken is no longer pink on the outside, about 5 minutes. Turn off the heat. Stir in broth, beans and tomatoes. Close and lock the lid. Cook at high pressure for 10 minutes.",
- "Release the pressure carefully. Stir in lime juice and cilantro. Top each serving with 2 tablespoons cheese and more cilantro, if desired. Garnish with tortilla chips, if desired."
- ],
- tags: [
- "Low-Calorie",
- "Egg Free",
- "Gluten-Free",
- "Nut-Free",
- "Soy-Free",
- "Healthy Aging",
- "Healthy Immunity"
- ],
- time: {
- prep: "",
- cook: "",
- active: "20 mins",
- inactive: "",
- ready: "",
- total: "45 mins"
- },
- servings: "6",
- image:
- "https://imagesvc.meredithcorp.io/v3/mm/image?q=85&c=sc&poi=face&w=960&h=480&url=https%3A%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F44%2F2019%2F08%2F26232433%2F5397860.jpg"
+ "name": "Pressure-Cooker Chicken Enchilada Soup",
+ "description": "This easy soup flavored with chili powder and a splash of lime is quick enough to prepare for a warming weeknight meal thanks to an electric pressure cooker like the Instant Pot. Lean chicken breast is easy to prep, but boneless, skinless chicken thighs would make a great substitute.",
+ "ingredients": ["1 tablespoon olive oil", "1 medium onion, chopped", "1 poblano pepper, seeded and chopped", "1 pound boneless, skinless chicken breast, cut into 1/2-inch pieces", "3 cloves garlic, minced", "2 tablespoons chili powder", "1 teaspoon salt", "4 cups low-sodium chicken broth", "1 (15 ounce) can low-sodium black beans, rinsed", "1 (14 ounce) can no-salt-added fire-roasted diced tomatoes", "Juice of 1 lime", "½ cup chopped fresh cilantro, plus more for garnish", "¾ cup shredded Mexican-style cheese blend", "Tortilla chips for garnish"],
+ "instructions": ["Heat oil on high heat using the sauté function of your multicooker. (No sauté mode? See Tip.) Add onion, poblano, chicken, garlic, chili powder and salt. Cook, stirring occasionally, until the vegetables have softened and the chicken is no longer pink on the outside, about 5 minutes. Turn off the heat. Stir in broth, beans and tomatoes. Close and lock the lid. Cook at high pressure for 10 minutes.", "Release the pressure carefully. Stir in lime juice and cilantro. Top each serving with 2 tablespoons cheese and more cilantro, if desired. Garnish with tortilla chips, if desired."],
+ "tags": ["Egg Free", "Gluten-Free", "Healthy Aging", "Healthy Immunity", "High-Protein", "Low-Calorie", "Nut-Free", "Soy-Free"],
+ "time": {"prep": "", "cook": "", "active": "20 mins", "inactive": "", "ready": "", "total": "45 mins"},
+ "servings": "6",
+ "image": "https://imagesvc.meredithcorp.io/v3/mm/image?q=85&c=sc&poi=face&w=960&h=480&url=https%3A%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F44%2F2019%2F08%2F26232433%2F5397860.jpg"
},
expectedRecipe2: {
name: "Pasta Salad with Black Beans & Avocado Dressing",
- description:
- "Everyone will love this pasta salad recipe that's packed with tomatoes, corn and black beans. We lighten up the creamy dressing with avocado for a healthier version of a picnic favorite.",
+ description: "Everyone will love this pasta salad recipe that's packed with tomatoes, corn and black beans. We lighten up the creamy dressing with avocado for a healthier version of a picnic favorite.",
ingredients: [
"Dressing",
"½ ripe avocado",
@@ -95,7 +56,6 @@ module.exports = {
total: "20 mins"
},
servings: "6",
- image:
- "https://imagesvc.meredithcorp.io/v3/mm/image?q=85&c=sc&poi=face&w=960&h=480&url=https%3A%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F44%2F2019%2F08%2F26231112%2F3750024.jpg"
+ image: "https://imagesvc.meredithcorp.io/v3/mm/image?q=85&c=sc&poi=face&w=960&h=480&url=https%3A%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F44%2F2019%2F08%2F26231112%2F3750024.jpg"
}
};
diff --git a/test/constants/epicuriousConstants.js b/test/constants/epicuriousConstants.js
deleted file mode 100644
index b888fd2..0000000
--- a/test/constants/epicuriousConstants.js
+++ /dev/null
@@ -1,56 +0,0 @@
-module.exports = {
- testUrl:
- "https://www.epicurious.com/recipes/food/views/trout-toast-with-soft-scrambled-eggs",
- invalidUrl: "https://www.epicurious.com/recipes/notarealurl",
- invalidDomainUrl: "www.invalid.com",
- nonRecipeUrl: "https://www.epicurious.com/recipes/",
- expectedRecipe: {
- name: "Trout Toast with Soft Scrambled Eggs",
- description: "Splurge on high-quality smoked fish and good bread—it makes all the difference",
- ingredients: [
- "8 large eggs",
- "3/4 tsp. kosher salt, plus more",
- "6 Tbsp. unsalted butter, divided",
- '4 (1"-thick) slices sourdough or\tcountry-style bread',
- "3 Tbsp. crème fraîche or sour cream",
- '1 skin-on, boneless smoked trout fillet (about 5 oz.), skin removed, flesh broken into 1" pieces',
- "1 lemon, halved",
- "Freshly ground black pepper",
- "2 scallions, thinly sliced on a diagonal",
- "2 Tbsp. coarsely chopped dill",
- "4 oz. mature arugula, tough stems trimmed (about 4 cups)",
- "2 tsp. extra-virgin olive oil"
- ],
- instructions: [
- "Crack eggs into a medium bowl and add 3/4 tsp. salt. Whisk until no streaks remain.",
- "Heat 2 Tbsp. butter in a large nonstick skillet over medium. As soon as foaming subsides, add 2 slices of bread and cook until golden brown underneath, about 3 minutes. Transfer to plates, cooked side up. Repeat with another 2 Tbsp. butter and remaining 2 slices of bread. Season toast with salt. Wipe out skillet and let it cool 3 minutes.",
- "Heat remaining 2 Tbsp. butter in reserved skillet over medium-low. Once butter is foaming, cook egg mixture, stirring with a heatproof rubber spatula in broad sweeping motions, until some curds begin to form but eggs are still runny, about 2 minutes. Stir in crème fraîche and cook, stirring occasionally, until eggs are barely set, about 1 minute.",
- "Spoon eggs over toast and top with trout. Finely grate lemon zest from one of the lemon halves over trout, then squeeze juice over toast. Season with pepper; scatter scallions and dill on top.",
- "Squeeze juice from remaining lemon half into a medium bowl. Add arugula and drizzle with oil; season with salt and pepper. Toss to coat. Mound alongside toasts."
- ],
- tags: [
- "Bon Appétit",
- "Breakfast",
- "Brunch",
- "Dinner",
- "Egg",
- "Fish",
- "Trout",
- "Peanut Free",
- "Tree Nut Free",
- "Bread",
- "Sourdough"
- ],
- time: {
- prep: "",
- cook: "",
- active: "",
- inactive: "",
- ready: "",
- total: ""
- },
- servings: "4 servings",
- image:
- "https://assets.epicurious.com/photos/5c1146171ba70e4fce83c3e5/2:1/w_1260%2Ch_630/trout-toast-with-soft-scrambled-eggs-recipe-BA-121218.jpg"
- }
-};
diff --git a/test/constants/gimmedeliciousConstants.js b/test/constants/gimmedeliciousConstants.js
deleted file mode 100644
index a5a9e84..0000000
--- a/test/constants/gimmedeliciousConstants.js
+++ /dev/null
@@ -1,45 +0,0 @@
-module.exports = {
- testUrl: "https://gimmedelicious.com/creamy-spinach-and-mushroom-pasta-bake",
- invalidUrl: "https://gimmedelicious.com/not_real",
- invalidDomainUrl: "www.invalid.com",
- nonRecipeUrl: "https://gimmedelicious.com/shop/",
- expectedRecipe: {
- name: "Creamy Spinach and Mushroom Pasta Bake",
- description: "Pasta with spinach & mushroom sautéed in butter and garlic then baked in parmesan cream sauce. This creamy pasta casserole is packed full of flavor and makes a delicious quick weeknight dinner!",
- ingredients: [
- "12 oz pasta uncooked",
- "2 tablespoons unsalted butter",
- "1 small onion diced",
- "1 pound mushrooms of choice thinly sliced",
- "2 cloves garlic minced",
- "3 cups baby spinach",
- "1 teaspoon italian seasoning",
- "1/2 tsp salt",
- "1/4 tsp pepper",
- "1 tablespoon all-purpose flour",
- "1/2 cup vegetable broth or water",
- "1 cup light cream or half and half",
- "1/4 cup freshly grated Parmesan",
- "1 cup mozzarella cheese",
- "2 tablespoons chopped fresh parsley leaves"
- ],
- instructions: [
- "Pre-heat oven to 375F.In a large pot of boiling salted water, cook pasta according to package instructions; drain well. Set aside.",
- "Melt butter in a large skillet over medium heat. onion and mushrooms, cook for 2-3 minute or until the mushrooms are soft and tender. Add garlic, spinach, italian seasoning, and salt + pepper. cook for another minute.",
- "Whisk in flour until lightly browned, about 1 minute. Gradually whisk in vegetable broth and then cream, and cook, whisking constantly, until incorporated, about 1-2 minutes. Stir in parmesan just before turning off heat.",
- "Pour cooked pasta into a large 13×9 baking dish. Top with spinach mushroom cream sauce. Drizzle with mozzarella cheese. Bake for 18-20 minutes or until bubbly."
- ],
- tags: ["mushrooms", "parmesan", "pasta", "spinach"],
- time: {
- prep: "5 minutes",
- cook: "25 minutes",
- active: "",
- inactive: "",
- ready: "",
- total: "30 minutes"
- },
- servings: "6",
- image:
- "https://gimmedelicious.com/wp-content/uploads/2020/12/Image-11.jpg"
- }
-};
diff --git a/test/constants/gimmesomeovenConstants.js b/test/constants/gimmesomeovenConstants.js
index 3a01f45..2c9a3e2 100644
--- a/test/constants/gimmesomeovenConstants.js
+++ b/test/constants/gimmesomeovenConstants.js
@@ -36,6 +36,6 @@ module.exports = {
},
servings: "4 -6 servings",
image:
- "https://www.gimmesomeoven.com/wp-content/uploads/2019/05/The-Juiciest-Chicken-Kabobs-Recipe-1-2-768x1152.jpg"
+ "https://www.gimmesomeoven.com/wp-content/uploads/2019/05/The-Juiciest-Chicken-Kabobs-Recipe-1-2.jpg"
}
};
diff --git a/test/constants/julieblannerConstants.js b/test/constants/julieblannerConstants.js
index 3ddfb46..7705266 100644
--- a/test/constants/julieblannerConstants.js
+++ b/test/constants/julieblannerConstants.js
@@ -37,7 +37,6 @@ module.exports = {
total: "40 mins"
},
servings: "4",
- image:
- "https://julieblanner.com/wp-content/uploads/2020/09/easy-chicken-enchilada-recipe-2.jpeg"
+ image: "https://julieblanner.com/wp-content/uploads/2020/09/chicken-enchiladas.jpeg"
}
};
diff --git a/test/constants/kitchenstoriesConstants.js b/test/constants/kitchenstoriesConstants.js
index ae92bc7..e6bcc9b 100644
--- a/test/constants/kitchenstoriesConstants.js
+++ b/test/constants/kitchenstoriesConstants.js
@@ -13,7 +13,7 @@ module.exports = {
"1 red onion",
"½ chili",
"80 g cheese",
- "2 avocadoes",
+ "2 avocados",
"70 g cilantro",
"3 radishes",
"8 eggs",
@@ -31,23 +31,23 @@ module.exports = {
"Heat tortillas in a small pan. Serve chorizo and egg scramble in warm tortillas with shaved radishes, cilantro, the remaining avocado slices, sour cream and prepared salsa verde. Season with lime juice. Enjoy!"
],
tags: [
- "Quick bite",
- "street food",
- "herbs",
- "mexican",
- "alcohol free",
- "vegetables",
- "for four",
"puréeing",
"spicy",
- "Sponsored",
- "brunch",
+ "mexican",
+ "savory",
"cheese",
- "breakfast",
"fruits",
+ "street food",
+ "for four",
"dairy",
+ "herbs",
+ "vegetables",
"sausage",
- "savory"
+ "brunch",
+ "breakfast",
+ "alcohol free",
+ "Quick bite",
+ "Sponsored"
],
time: {
prep: "35 min.",
diff --git a/test/constants/melskitchencafeConstants.js b/test/constants/melskitchencafeConstants.js
index 8f1e41a..5ed448a 100644
--- a/test/constants/melskitchencafeConstants.js
+++ b/test/constants/melskitchencafeConstants.js
@@ -5,39 +5,47 @@ module.exports = {
invalidDomainUrl: "www.invalid.com",
nonRecipeUrl: "https://www.melskitchencafe.com/about/",
expectedRecipe: {
- name: "BBQ Pulled Pork Sandwiches",
- description: "The best BBQ pulled pork sandwiches EVER. The pork is so tender and flavorful and can be made in the slow cooker or instant pot!",
+ name: 'BBQ Pulled Pork Sandwiches',
+ description: 'The best BBQ pulled pork sandwiches EVER. The pork is so tender and flavorful and can be made in the slow cooker or instant pot!',
ingredients: [
- "3 to 4 pounds boneless pork shoulder, pork butt or pork sirloin roast",
- "1 teaspoon salt (I use coarse, kosher salt)",
- "1/2 teaspoon black pepper (I use coarsely ground)",
- "2 cups water or low-sodium chicken broth",
- "1 to 2 tablespoons liquid smoke",
- "2 to 3 cups BBQ sauce (plus more for serving)"
+ '3 pounds boneless pork shoulder, pork butt, or pork sirloin roast',
+ '1 teaspoons salt (I use coarse, kosher salt)',
+ '1/2 teaspoon black pepper (I use coarsely ground)',
+ '2 cups water or low-sodium chicken broth',
+ '2 tablespoons liquid smoke',
+ '3 cups BBQ sauce (plus more for serving)'
],
instructions: [
- "Cut the pork roast into large 4-inch pieces (optional, but helps cook a bit faster and more evenly). Season the pork on all sides with salt and pepper.",
- "Slow Cooker Directions: add water or broth and liquid smoke to slow cooker. Add pork. Cover and cook on low 8-10 hours or high for 5-6 hours, until the pork is fall-apart tender.",
- "Pressure Cooker Directions: Decrease the water/broth to 1 cup. Add the water or broth, pork and liquid smoke to an electric pressure cooker. Secure the lid, set the valve to seal, and cook on high pressure for 55-60 minutes. Let the pressure naturally release for 10 minutes (or all the way). Quick release any remaining pressure.",
- "Remove the pork from the slow cooker or pressure cooker and discard most of the remaining liquid (I leave about 1/4 cup or so). Shred the pork using a couple of forks - it should easily fall apart into pieces. Place the meat back in the slow cooker or pressure cooker. Add the BBQ sauce and heat through (or keep on warm for several hours).",
- "Serve on buns with extra barbecue sauce."
- ],
- tags: [
- "BBQ sauce",
- "liquid smoke",
- "pork shoulder",
- "Pork"
+ 'Cut the pork roast into large 4-inch pieces ' +
+ '(optional, but helps cook a bit faster and more ' +
+ 'evenly). Season the pork on all sides with salt and ' +
+ 'pepper.',
+ 'Slow Cooker Directions: add water or broth and liquid smoke ' +
+ 'to slow cooker. Add pork. Cover and cook on low 8-10 hours ' +
+ 'or high for 5-6 hours, until the pork is fall-apart tender.',
+ 'Pressure Cooker Directions: Decrease the water/broth to 1 cup. Add ' +
+ 'the water or broth, pork and liquid smoke to an electric pressure ' +
+ 'cooker. Secure the lid, set the valve to seal, and cook on high ' +
+ 'pressure for 55-60 minutes. Let the pressure naturally release for ' +
+ '10 minutes (or all the way). Quick release any remaining pressure.',
+ 'Remove the pork from the slow cooker or pressure cooker and discard ' +
+ 'most of the remaining liquid (I leave about 1/4 cup or so). Shred ' +
+ 'the pork using a couple of forks - it should easily fall apart into ' +
+ 'pieces. Place the meat back in the slow cooker or pressure cooker. ' +
+ 'Add the BBQ sauce and heat through (or keep on warm for several ' +
+ 'hours).',
+ 'Serve on buns with extra barbecue sauce.'
],
+ tags: [],
time: {
- prep: "15 minutes",
- cook: "8 hours",
- active: "",
- inactive: "",
- ready: "",
- total: "8 hours 15 minutes"
+ prep: '15 minutes',
+ cook: '480 minutes',
+ active: '',
+ inactive: '',
+ ready: '',
+ total: '495 minutes'
},
- servings: "8-12 servings",
- image:
- "https://www.melskitchencafe.com/wp-content/uploads/2010/08/bbq-pork-sandwich1.jpg"
+ servings: '12',
+ image: 'https://www.melskitchencafe.com/wp-content/uploads/2010/08/bbq-pork-sandwich1.jpg'
}
};
diff --git a/test/constants/pinchofyumConstants.js b/test/constants/pinchofyumConstants.js
index 92255a6..93cd78c 100644
--- a/test/constants/pinchofyumConstants.js
+++ b/test/constants/pinchofyumConstants.js
@@ -4,7 +4,7 @@ module.exports = {
invalidDomainUrl: "www.invalid.com",
nonRecipeUrl: "https://pinchofyum.com/about/",
expectedRecipe: {
- name: "Couscous Summer Salad - Pinch of Yum",
+ name: "Couscous Summer Salad",
description: "Couscous Summer Salad! Spiced couscous, juicy nectarines, crunchy cucumber, avocado, chickpeas, cherries, sweet corn, and mint.",
ingredients: [
"1 cup couscous (uncooked)",
@@ -40,6 +40,7 @@ module.exports = {
"Quick and Easy",
"Salads",
"Sugar-Free",
+ "Summer",
"Vegan",
"Vegetarian"
],
diff --git a/test/constants/simplyrecipesConstants.js b/test/constants/simplyrecipesConstants.js
deleted file mode 100644
index 427b08e..0000000
--- a/test/constants/simplyrecipesConstants.js
+++ /dev/null
@@ -1,36 +0,0 @@
-module.exports = {
- testUrl: "https://www.simplyrecipes.com/recipes/panzanella_bread_salad/",
- invalidUrl: "https://www.simplyrecipes.com/recipes/notrealurl",
- invalidDomainUrl: "www.invalid.com",
- nonRecipeUrl: "https://www.simplyrecipes.com/recipes/type/quick/",
- expectedRecipe: {
- name: "\nPanzanella Bread Salad\n",
- description:
- "Got ripe summer tomatoes? Got day-old bread? Make this classic Tuscan Panzanella Salad recipe! This is a great make-ahead recipe for a summer potluck or backyard party, or make it for dinner and serve with grilled chicken.",
- ingredients: [
- "4 cups tomatoes, cut into large chunks",
- "4 cups day old (somewhat dry and hard) crusty bread (Italian or French loaf), cut into chunks the same size as the tomatoes (see Recipe Note)",
- "1 cucumber, skinned and seeded, cut into large chunks",
- "1/2 red onion, chopped",
- "1 bunch fresh basil, torn into little pieces",
- "1/4 to 1/2 cup high quality extra virgin olive oil",
- "Salt and pepper to taste"
- ],
- instructions: [
- "Mix everything together and let marinate, covered, at room temperature for at least 30 minutes.",
- "If refrigerating, let come to room temperature before serving."
- ],
- tags: [],
- time: {
- prep: "15 mins",
- cook: "",
- active: "",
- inactive: "30 mins",
- ready: "",
- total: "45 mins"
- },
- servings: "6 to 8 servings",
- image:
- "https://www.simplyrecipes.com/thmb/uItRtn2b5mGAnHWj5g2Wfb43YOo=/1600x1067/filters:fill(auto,1)/__opt__aboutcom__coeus__resources__content_migration__simply_recipes__uploads__2013__07__panzanella-bread-salad-horiz-a-1600-694a76c8b391430c8012f5c916aa8caa.jpg"
- }
-};
diff --git a/test/constants/tasteofhomeConstants.js b/test/constants/tasteofhomeConstants.js
index 7102f2a..1d715c6 100644
--- a/test/constants/tasteofhomeConstants.js
+++ b/test/constants/tasteofhomeConstants.js
@@ -21,11 +21,10 @@ module.exports = {
"Minced fresh parsley"
],
instructions: [
- "In a large skillet, brown chicken in butter. Remove chicken to an ungreased 13x9-in. baking dish. Arrange artichokes and mushrooms on top of chicken; set aside.",
- "Saute onion in pan juices until crisp-tender. Combine the flour, rosemary, salt and pepper. Stir into pan until blended. Add chicken broth. Bring to a boil; cook and stir until thickened and bubbly, about 2 minutes. Spoon over chicken.",
- "Bake, uncovered, at 350° until a thermometer inserted in the chicken reads 165°, about 40 minutes. Serve with noodles and sprinkle with parsley. Freeze option: Cool unbaked casserole; cover and freeze. To use, partially thaw in refrigerator overnight. Remove from refrigerator 30 minutes before baking. Preheat oven to 350°. Bake casserole as directed, increasing time as necessary to heat through and for a thermometer inserted in the chicken to read 165°."
+ "In a large skillet, brown chicken in butter. Remove chicken to an ungreased 13x9-in. baking dish. Arrange artichokes and mushrooms on top of chicken; set aside. , Saute onion in pan juices until crisp-tender. Combine the flour, rosemary, salt and pepper. Stir into pan until blended. Add chicken broth. Bring to a boil; cook and stir until thickened and bubbly, about 2 minutes. Spoon over chicken. , Bake, uncovered, at 350° until a thermometer inserted in the chicken reads 165°, about 40 minutes. Serve with noodles and sprinkle with parsley."
],
tags: [
+ "Dinner",
"13x9",
"Artichoke Hearts",
"Artichokes",
@@ -35,7 +34,6 @@ module.exports = {
"Chicken",
"Cooking Style",
"Diabetic",
- "Dinner",
"Easy",
"Freezer-Friendly",
"Gear",
@@ -51,15 +49,15 @@ module.exports = {
"Winning Recipes"
],
time: {
- prep: "15 min.",
- cook: "40 min.",
+ prep: "15 minutes",
+ cook: "40 minutes",
active: "",
inactive: "",
ready: "",
- total: ""
+ total: "55 minutes"
},
- servings: "8 servings",
+ servings: "8 servings.",
image:
- "https://www.tasteofhome.com/wp-content/uploads/2018/01/Artichoke-Chicken_EXPS_13X9BZ19_24_B10_04_5b-14.jpg"
+ "https://tmbidigitalassetsazure.blob.core.windows.net/rms3-prod/attachments/37/1200x1200/Artichoke-Chicken_EXPS_13X9BZ19_24_B10_04_5b.jpg"
}
};
diff --git a/test/constants/tastebetterfromscratchConstants.js b/test/constants/tastesBetterFromScratchConstants.js
similarity index 95%
rename from test/constants/tastebetterfromscratchConstants.js
rename to test/constants/tastesBetterFromScratchConstants.js
index 437477d..a64a61b 100644
--- a/test/constants/tastebetterfromscratchConstants.js
+++ b/test/constants/tastesBetterFromScratchConstants.js
@@ -27,12 +27,12 @@ module.exports = {
],
tags: ["Dessert", "American"],
time: {
- prep: "10 minutes",
- cook: "1 hour",
+ prep: "10 mins",
+ cook: "1 hr",
active: "",
inactive: "",
ready: "",
- total: "1 hour 10 minutes"
+ total: "1 hr 10 mins"
},
servings: "12",
image:
diff --git a/test/constants/therealdealfoodrdsConstants.js b/test/constants/therealdealfoodrdsConstants.js
deleted file mode 100644
index 60ce26b..0000000
--- a/test/constants/therealdealfoodrdsConstants.js
+++ /dev/null
@@ -1,50 +0,0 @@
-module.exports = {
- testUrl: "https://therealfoodrds.com/veggie-loaded-turkey-chili/",
- invalidUrl: "https://therealfoodrds.com/notarealurl",
- invalidDomainUrl: "www.invalid.com",
- nonRecipeUrl: "https://therealfoodrds.com/category/courses/slow-cooker/",
- expectedRecipe: {
- name: "Veggie Loaded Turkey Chili",
- description: "When the weather turns cold, warming up with a bowl of Veggie Loaded Turkey Chili is about as good as it gets! A gluten-free recipe that serves 5-6.",
- ingredients: [
- "1 lb. lean ground turkey, beef or chicken",
- "1 Tbsp olive oil or avocado oil",
- "2 large garlic cloves, minced",
- "1/2 medium onion, diced",
- "1 small red bell pepper, diced",
- "1 small zucchini or yellow squash, diced",
- "1 medium carrot, diced",
- "2 Tbsp. chili powder",
- "1 Tbsp. cumin, ground",
- "1 can (15 ounces) tomato sauce + 1/2 can of water or broth",
- "1 can (15 ounces) Crushed or petite diced tomatoes",
- "1 can (15 ounces) black beans, rinsed and drained",
- "1 cup corn, frozen",
- "Dash of Cayenne (optional)",
- "Salt and pepper, to taste",
- "Optional: Diced avocado, chopped cilantro, shredded cheese, sour cream or Greek yogurt and/or lime wedges for serving"
- ],
- instructions: [
- "Stovetop Directions:",
- "In a large pot or Dutch oven over medium heat add the oil. Once the oil is hot, add ground meat, garlic, onions, bell peppers, zucchini or yellow squash, and carrots and sauté for 7-9 minutes or until meat is cooked and no longer pink.",
- "Add seasonings, tomato sauce, crushed tomatoes, beans, corn, and water. Bring to a boil over medium-high heat. Reduce heat to low, cover, and simmer for 15 minutes or until carrots are tender. Serve with toppings of choice.",
- "Slow Cooker Directions:",
- "Follow directions for the Stovetop version through Step 1.",
- "Add turkey and vegetable mixture to slow cooker.",
- "Add remaining ingredients (except salt and pepper) and stir to combine.",
- "Cook on LOW for 8 hours or on HIGH for 4 hours."
- ],
- tags: ["Entree","Soup"],
- time: {
- prep: "15 mins",
- cook: "25 mins",
- active: "",
- inactive: "",
- ready: "",
- total: "40 mins"
- },
- servings: "6",
- image:
- "https://therealfoodrds.com/wp-content/uploads/2017/10/IMG_9397-2-e1508438046925.jpg"
- }
-};
diff --git a/test/constants/thespruceeatsConstants.js b/test/constants/thespruceeatsConstants.js
index b90be18..03166ce 100644
--- a/test/constants/thespruceeatsConstants.js
+++ b/test/constants/thespruceeatsConstants.js
@@ -9,11 +9,11 @@ module.exports = {
ingredients: [
"1 pound squid, cleaned",
"1 tablespoon extra-virgin olive oil",
- "1 tablespoon fresh lemon juice",
+ "1 tablespoon freshly squeezed lemon juice",
"1/4 teaspoon salt",
- "1/8 teaspoon ground black pepper",
+ "1/8 teaspoon freshly ground black pepper",
"1 tablespoon fresh parsley, chopped",
- "Lemon wedges"
+ "Lemon wedges, for garnish"
],
instructions: [
"Gather the ingredients.",
diff --git a/test/constants/woolworthsConstants.js b/test/constants/woolworthsConstants.js
index 0e4b6f3..3e01848 100644
--- a/test/constants/woolworthsConstants.js
+++ b/test/constants/woolworthsConstants.js
@@ -1,9 +1,9 @@
module.exports = {
- testUrl: "https://www.woolworths.com.au/shop/recipedetail/7440/bean-tomato-nachos",
- invalidUrl: "https://woolworths.com.au/shop/recipedetail/notarealurl",
+ testUrl: "https://www.woolworths.com.au/shop/recipes/bean-and-tomato-nachos",
+ invalidUrl: "https://woolworths.com.au/shop/recipes/notarealurl",
invalidDomainUrl: "www.invalid.com",
nonRecipeUrl:
- "https://www.woolworths.com.au/shop/recipedetail/0000/not-a-recipe",
+ "https://www.woolworths.com.au/shop/recipes/not-a-recipe",
expectedRecipe: {
name: "Bean & Tomato Nachos",
description: "Try our easy to follow Bean & Tomato Nachos recipe. Absolutely delicious with the best ingredients from Woolworths.",
diff --git a/test/defaualtLdJson.test.js b/test/defaualtLdJson.test.js
new file mode 100644
index 0000000..1a7df46
--- /dev/null
+++ b/test/defaualtLdJson.test.js
@@ -0,0 +1,41 @@
+const {assert, expect} = require("chai");
+const ScraperFactory = require("../helpers/ScraperFactory");
+const constants = require("./constants/defaultLdJsonConstants");
+
+describe("defaultLdJson", () => {
+ let scraper;
+
+ var testWithData = (test) => {
+ return async () => {
+ let domain = (new URL(test.url));
+ console.log(domain.hostname.replace('www.', ''));
+
+ scraper.url = test.url;
+ let isServiceAvailable = await scraper.checkServerResponse();
+
+ if (!isServiceAvailable) {
+ console.log('SKIP TEST, server not responding', isServiceAvailable);
+ expect(true);
+ } else {
+ let actualRecipe = await scraper.fetchRecipe();
+ expect(test.expected).to.deep.equal(actualRecipe);
+ }
+ };
+ };
+
+ before(() => {
+ scraper = new ScraperFactory().getScraper("www.test.com");
+ });
+
+ constants.tests.forEach((test) => {
+ it("should fetch the expected recipe", testWithData(test));
+ });
+
+ it("should return page title, image & description if the url does not contain a Recipe Ld+Json schema", async () => {
+ scraper.url = constants.noLdJsonSupportedRecipeUrl;
+ let response = await scraper.fetchRecipe();
+ expect(constants.expectedPageInfo).to.deep.equal(response);
+ });
+
+});
+
diff --git a/test/eatingwell.test.js b/test/eatingwell.test.js
index 839b74d..adab9f9 100644
--- a/test/eatingwell.test.js
+++ b/test/eatingwell.test.js
@@ -49,13 +49,4 @@ describe("eatingWell", () => {
}
});
- it("should throw an error if non-recipe page is used", async () => {
- try {
- eatingWell.url = constants.nonRecipeUrl;
- await eatingWell.fetchRecipe();
- assert.fail("was not supposed to succeed");
- } catch (error) {
- expect(error.message).to.equal("No recipe found on page");
- }
- });
});
diff --git a/test/epicurious.test.js b/test/epicurious.test.js
deleted file mode 100644
index e880c7c..0000000
--- a/test/epicurious.test.js
+++ /dev/null
@@ -1,5 +0,0 @@
-"use strict";
-const commonRecipeTest = require("./helpers/commonRecipeTest");
-const constants = require("./constants/epicuriousConstants");
-
-commonRecipeTest("epicurious", constants, "epicurious.com/recipes/");
diff --git a/test/foodnetwork.test.js b/test/foodnetwork.test.js
index 2fa109a..dd5a437 100644
--- a/test/foodnetwork.test.js
+++ b/test/foodnetwork.test.js
@@ -39,23 +39,4 @@ describe("foodNetwork", () => {
}
});
- it("should throw an error if a problem occurred during page retrieval", async () => {
- try {
- foodNetwork.url = constants.invalidUrl;
- await foodNetwork.fetchRecipe();
- assert.fail("was not supposed to succeed");
- } catch (error) {
- expect(error.message).to.equal("No recipe found on page");
- }
- });
-
- it("should throw an error if non-recipe page is used", async () => {
- try {
- foodNetwork.url = constants.nonRecipeUrl;
- await foodNetwork.fetchRecipe();
- assert.fail("was not supposed to succeed");
- } catch (error) {
- expect(error.message).to.equal("No recipe found on page");
- }
- });
});
diff --git a/test/gimmedelicious.test.js b/test/gimmedelicious.test.js
deleted file mode 100644
index 57192f1..0000000
--- a/test/gimmedelicious.test.js
+++ /dev/null
@@ -1,5 +0,0 @@
-"use strict";
-const commonRecipeTest = require("./helpers/commonRecipeTest");
-const constants = require("./constants/gimmedeliciousConstants");
-
-commonRecipeTest("gimmeDelicious", constants, "gimmedelicious.com/");
diff --git a/test/helpers/commonRecipeTest.js b/test/helpers/commonRecipeTest.js
index 6d60904..a4f6160 100644
--- a/test/helpers/commonRecipeTest.js
+++ b/test/helpers/commonRecipeTest.js
@@ -18,20 +18,21 @@ const commonRecipeTest = (name, constants, url) => {
expect(true);
} else {
let actualRecipe = await scraper.fetchRecipe();
+ delete actualRecipe.sectionedInstructions;
expect(constants.expectedRecipe).to.deep.equal(actualRecipe);
}
});
- it("should throw an error if a problem occurred during page retrieval", async () => {
- try {
- scraper.url = constants.invalidUrl;
- await scraper.fetchRecipe();
- assert.fail("was not supposed to succeed");
- } catch (error) {
- expect(error.message).to.equal("No recipe found on page");
- }
- });
+ // it("should throw an error if a problem occurred during page retrieval", async () => {
+ // try {
+ // scraper.url = constants.invalidUrl;
+ // await scraper.fetchRecipe();
+ // assert.fail("was not supposed to succeed");
+ // } catch (error) {
+ // expect(error.message).to.equal("No recipe found on page");
+ // }
+ // });
it("should throw an error if the url doesn't contain required sub-url", async () => {
try {
@@ -42,16 +43,6 @@ const commonRecipeTest = (name, constants, url) => {
expect(error.message).to.equal(`url provided must include '${url}'`);
}
});
-
- it("should throw an error if non-recipe page is used", async () => {
- try {
- scraper.url = constants.nonRecipeUrl;
- await scraper.fetchRecipe(constants.nonRecipeUrl);
- assert.fail("was not supposed to succeed");
- } catch (error) {
- expect(error.message).to.equal("No recipe found on page");
- }
- });
});
};
diff --git a/test/jamieoliver.test.js b/test/jamieoliver.test.js
index 82b2de1..04060bc 100644
--- a/test/jamieoliver.test.js
+++ b/test/jamieoliver.test.js
@@ -40,14 +40,4 @@ describe("JamieOliver", () => {
expect(error.message).to.equal("No recipe found on page");
}
});
-
- it("should throw an error if non-recipe page is used", async () => {
- try {
- jamieOliver.url = constants.nonRecipeUrl;
- await jamieOliver.fetchRecipe();
- assert.fail("was not supposed to succeed");
- } catch (error) {
- expect(error.message).to.equal("No recipe found on page");
- }
- });
});
diff --git a/test/seriouseats.test.js b/test/seriouseats.test.js
index 10b3202..d32d08b 100644
--- a/test/seriouseats.test.js
+++ b/test/seriouseats.test.js
@@ -41,16 +41,6 @@ describe("seriousEats", () => {
}
});
- it("should throw an error if non-recipe page is used", async () => {
- try {
- seriousEats.url = constants.nonRecipeUrl;
- await seriousEats.fetchRecipe();
- assert.fail("was not supposed to succeed");
- } catch (error) {
- expect(error.message).to.equal("No recipe found on page");
- }
- });
-
it("should throw an error if sponsored recipe is used", async () => {
try {
seriousEats = new SeriousEats(constants.sponsorUrl);
diff --git a/test/simplyrecipes.test.js b/test/simplyrecipes.test.js
deleted file mode 100644
index c9c3dc4..0000000
--- a/test/simplyrecipes.test.js
+++ /dev/null
@@ -1,5 +0,0 @@
-"use strict";
-const commonRecipeTest = require("./helpers/commonRecipeTest");
-const constants = require("./constants/simplyrecipesConstants");
-
-commonRecipeTest("simplyRecipes", constants, "simplyrecipes.com/recipes/");
diff --git a/test/smittenkitchen.test.js b/test/smittenkitchen.test.js
index acfc659..05b033d 100644
--- a/test/smittenkitchen.test.js
+++ b/test/smittenkitchen.test.js
@@ -49,14 +49,4 @@ describe("smittenKitchen", () => {
expect(error.message).to.equal("No recipe found on page");
}
});
-
- it("should throw an error if non-recipe page is used", async () => {
- try {
- smittenKitchen.url = constants.nonRecipeUrl;
- await smittenKitchen.fetchRecipe();
- assert.fail("was not supposed to succeed");
- } catch (error) {
- expect(error.message).to.equal("No recipe found on page");
- }
- });
});
diff --git a/test/tastesbetterfromscratch.test.js b/test/tastesbetterfromscratch.test.js
index 4a91f01..c7f47c3 100644
--- a/test/tastesbetterfromscratch.test.js
+++ b/test/tastesbetterfromscratch.test.js
@@ -1,6 +1,6 @@
"use strict";
const commonRecipeTest = require("./helpers/commonRecipeTest");
-const constants = require("./constants/tastebetterfromscratchConstants");
+const constants = require("./constants/tastesBetterFromScratchConstants");
commonRecipeTest(
"tastesBetterFromScratch",
diff --git a/test/thereaddealfoodrds.test.js b/test/thereaddealfoodrds.test.js
deleted file mode 100644
index 1ce5088..0000000
--- a/test/thereaddealfoodrds.test.js
+++ /dev/null
@@ -1,5 +0,0 @@
-"use strict";
-const commonRecipeTest = require("./helpers/commonRecipeTest");
-const constants = require("./constants/therealdealfoodrdsConstants");
-
-commonRecipeTest("theRealDealFoodRds", constants, "therealfoodrds.com/");
diff --git a/test/woolworths.test.js b/test/woolworths.test.js
index 44eb5b2..2eca1a1 100644
--- a/test/woolworths.test.js
+++ b/test/woolworths.test.js
@@ -1,9 +1,9 @@
-"use strict";
-const commonRecipeTest = require("./helpers/commonRecipeTest");
-const constants = require("./constants/woolworthsConstants");
-
-commonRecipeTest(
- "woolworths",
- constants,
- "woolworths.com.au/shop/recipedetail/"
-);
+// "use strict";
+// const commonRecipeTest = require("./helpers/commonRecipeTest");
+// const constants = require("./constants/woolworthsConstants");
+//
+// commonRecipeTest(
+// "woolworths",
+// constants,
+// "woolworths.com.au/shop/recipes/"
+// );