Skip to main content

์›น ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์—”๋“œ ํˆฌ ์—”๋“œ ํ…Œ์ŠคํŠธ ๋งŒ๋“ค๊ธฐ

Copilot Chat์€ ์—”๋“œํˆฌ์—”๋“œ ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

HTML์ด ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋˜๋ฏ€๋กœ ์›น ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์—”๋“œ ํˆฌ ์—”๋“œ ํ…Œ์ŠคํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๊ณ  ๋ณต์žกํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Copilot Chat์€ ์›น ํŽ˜์ด์ง€์™€ ์ƒํ˜ธ ์ž‘์šฉํ•˜๊ณ  ์˜ˆ์ƒ๋œ ๊ฒฐ๊ณผ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ์ œ์•ˆํ•˜์—ฌ ์›น ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์—”๋“œ ํˆฌ ์—”๋“œ ํ…Œ์ŠคํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ ์‹œ๋‚˜๋ฆฌ์˜ค

์›น ํŽ˜์ด์ง€์— ์ œํ’ˆ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•˜๋Š” React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒ์ƒํ•ด ๋ณด์„ธ์š”. ์ œํ’ˆ ์„ธ๋ถ€ ์ •๋ณด๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์—”๋“œ ํˆฌ ์—”๋“œ ํ…Œ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Copilot Chat์—๊ฒŒ ์ด๋Ÿฌํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';

const ProductDetails = ({ productId = '1' }) => {
  const [product, setProduct] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchProduct = async () => {
      try {
        const response = await fetch(`/api/product/${productId}`);
        if (!response.ok) {
          throw new Error('Product not found');
        }
        const data = await response.json();
        setProduct(data);
        setLoading(false);
      } catch (err) {
        setError(err.message);
        setLoading(false);
      }
    };

    fetchProduct();
    return;
  }, [productId]); // Add productId to dependency array

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      {product && (
        <div>
          <h2>{product.name}</h2>
          <p>{product.description}</p>
          <p>Price: ${product.price}</p>
        </div>
      )}
    </div>
  );
};

ProductDetails.propTypes = {
  productId: PropTypes.string
};

export default ProductDetails;

์˜ˆ์‹œ ํ”„๋กฌํ”„ํŠธ

์ฐธ๊ณ  ํ•ญ๋ชฉ

์ด ์˜ˆ์ œ์—์„œ๋Š” ์—”๋“œํˆฌ์—”๋“œ ํ…Œ์ŠคํŠธ์— Playwright๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ Selenium ๋˜๋Š” Cypress์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Using Playwright, generate an e2e test to ensure the product displays correctly.

Copilot๋ฅผ ๋ชจ๋ธ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ธฐ์กด ํ…Œ์ŠคํŠธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ #file: path/to/test-file.js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ํ”„๋กฌํ”„ํŠธ์— ์ด ์ •๋ณด๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ ์‘๋‹ต

์ฐธ๊ณ  ํ•ญ๋ชฉ

๋‹ค์Œ ์‘๋‹ต์ด ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. Copilot Chat ์‘๋‹ต์€ ๋น„๊ฒฐ์ •์ ์ด๋ฏ€๋กœ ์—ฌ๊ธฐ์— ํ‘œ์‹œ๋œ ์‘๋‹ต๊ณผ ๋‹ค๋ฅธ ์‘๋‹ต์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Copilot๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์—”๋“œ ํˆฌ ์—”๋“œ ํ…Œ์ŠคํŠธ๋กœ ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.

import { test, expect } from '@playwright/test';

test.describe('ProductDetails Component', () => {
  test.beforeEach(async ({ page }) => {
    // Set up API mocking
    await page.route('/api/product/1', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          name: 'Test Product',
          description: 'This is a test product',
          price: 99.99
        })
      });
    });

    // Mock error response for product ID 999
    await page.route('/api/product/999', async (route) => {
      await route.fulfill({
        status: 404,
        contentType: 'application/json',
        body: JSON.stringify({ error: 'Product not found' })
      });
    });
  });

  test('displays loading state initially', async ({ page }) => {
    await page.goto('/product/1');
    const loadingElement = page.locator('text=Loading...');
    await expect(loadingElement).toBeVisible();
  });

  test('displays product details correctly', async ({ page }) => {
    await page.goto('/product/1');

    // Wait for loading to disappear
    await expect(page.getByText('Loading...')).toBeHidden();

    // Check all product details
    await expect(page.locator('h2')).toHaveText('Test Product');
    await expect(page.locator('text=This is a test product')).toBeVisible();
    await expect(page.locator('text=Price: $99.99')).toBeVisible();
  });

  test('displays error message when product not found', async ({ page }) => {
    await page.goto('/product/999');

    // Wait for loading to disappear
    await expect(page.getByText('Loading...')).toBeHidden();

    // Check error message
    await expect(page.locator('text=Error: Product not found')).toBeVisible();
  });
});

์ถ”๊ฐ€ ์ฐธ๊ณ  ์ž๋ฃŒ