align daily bulletin with Istanbul date
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
"count": 3
|
"count": 3
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"dailyBulletinHeading": true,
|
||||||
"analyticsTargetLabel": true,
|
"analyticsTargetLabel": true,
|
||||||
"icsImported": true,
|
"icsImported": true,
|
||||||
"icsStorageScoped": true,
|
"icsStorageScoped": true,
|
||||||
|
|||||||
@@ -2206,3 +2206,9 @@ Doğrulama: 293 otomatik test ve üretim derlemesi başarılı. Gece yarısı s
|
|||||||
`npm run qa:live -- https://ihaleist.com` komutu eklendi. Probe yalnızca ana sayfa, `/api/health` ve `/api/ready` uç noktalarını GET ile kontrol ediyor; authentication, veri yazma, ödeme veya sağlayıcı çağrısı yapmıyor. Ana sayfa ve health için güvenlik başlıklarını da zorunlu tutup JSON kanıtı `qa-live-runtime.json` içine yazıyor.
|
`npm run qa:live -- https://ihaleist.com` komutu eklendi. Probe yalnızca ana sayfa, `/api/health` ve `/api/ready` uç noktalarını GET ile kontrol ediyor; authentication, veri yazma, ödeme veya sağlayıcı çağrısı yapmıyor. Ana sayfa ve health için güvenlik başlıklarını da zorunlu tutup JSON kanıtı `qa-live-runtime.json` içine yazıyor.
|
||||||
|
|
||||||
6 Eylül 2026 çalıştırmasında ana sayfa ve health 200, readiness 404 döndü; üç güvenlik başlığı canlı yanıtlarda bulunmadı. Probe bu nedenle beklenen şekilde başarısız oldu. Bu sonuç yerel düzeltmelerin canlıya alınmadığını gösteren drift kanıtıdır.
|
6 Eylül 2026 çalıştırmasında ana sayfa ve health 200, readiness 404 döndü; üç güvenlik başlığı canlı yanıtlarda bulunmadı. Probe bu nedenle beklenen şekilde başarısız oldu. Bu sonuç yerel düzeltmelerin canlıya alınmadığını gösteren drift kanıtıdır.
|
||||||
|
|
||||||
|
### 2026-09-06 · Günlük bülten tarih ve erişilebilirlik düzeltmesi
|
||||||
|
|
||||||
|
Günlük bülten “bugün” hesabını tarayıcının yerel saatinden değil ortak İstanbul tarih anahtarından yapıyor. İhale başlığı artık klavye/ekran okuyucu için gerçek `button` olarak açılıyor; detay düğmesi de açık `type="button"` taşıyor.
|
||||||
|
|
||||||
|
Browser QA, dinamik sekme yüklemesi sonrası günlük bülten başlığını doğruluyor. 293 otomatik test ve üretim derlemesi başarılı.
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useApp } from '../../context/AppContext';
|
import { useApp } from '../../context/AppContext';
|
||||||
import { Newspaper, Calendar, Building2, Package, ArrowRight } from 'lucide-react';
|
import { Newspaper, Calendar, Building2, Package, ArrowRight } from 'lucide-react';
|
||||||
|
import { istanbulDateKey } from '../../services/tenderCalendar';
|
||||||
|
|
||||||
export const DailyBulletin = () => {
|
export const DailyBulletin = () => {
|
||||||
const { tenders, setActiveTenderDetail } = useApp();
|
const { tenders, setActiveTenderDetail } = useApp();
|
||||||
|
|
||||||
// Bugün: yayımlanma (ilan) tarihi bugün olanlar; ilan tarihi yoksa havuza az önce eklenenler.
|
// Bugün: yayımlanma (ilan) tarihi bugün olanlar; ilan tarihi yoksa havuza az önce eklenenler.
|
||||||
const bugun = new Date();
|
const isoBugun = istanbulDateKey();
|
||||||
const todayStr = `${String(bugun.getDate()).padStart(2, '0')}.${String(bugun.getMonth() + 1).padStart(2, '0')}.${bugun.getFullYear()}`;
|
const [bugunYil, bugunAy, bugunGun] = isoBugun.split('-');
|
||||||
const isoBugun = `${bugun.getFullYear()}-${String(bugun.getMonth() + 1).padStart(2, '0')}-${String(bugun.getDate()).padStart(2, '0')}`;
|
const todayStr = `${bugunGun}.${bugunAy}.${bugunYil}`;
|
||||||
const bugunMu = (v) => !!v && (String(v).startsWith(isoBugun) || String(v).slice(0, 10) === todayStr);
|
const bugunMu = (v) => !!v && (String(v).startsWith(isoBugun) || String(v).slice(0, 10) === todayStr);
|
||||||
const todayTenders = tenders.filter(t =>
|
const todayTenders = tenders.filter(t =>
|
||||||
bugunMu(t.ilanTarihi) || (!t.ilanTarihi && ((t.eklenmeZamani || '').includes('az') || (t.eklenmeZamani || '').includes('saat')))
|
bugunMu(t.ilanTarihi) || (!t.ilanTarihi && ((t.eklenmeZamani || '').includes('az') || (t.eklenmeZamani || '').includes('saat')))
|
||||||
@@ -42,11 +43,11 @@ export const DailyBulletin = () => {
|
|||||||
<span className="text-[10px] font-extrabold bg-blue-100 text-blue-800 px-2 py-0.5 rounded">
|
<span className="text-[10px] font-extrabold bg-blue-100 text-blue-800 px-2 py-0.5 rounded">
|
||||||
#{t.ikn}
|
#{t.ikn}
|
||||||
</span>
|
</span>
|
||||||
<h3
|
<h3>
|
||||||
onClick={() => setActiveTenderDetail(t)}
|
<button type="button" aria-haspopup="dialog" onClick={() => setActiveTenderDetail(t)}
|
||||||
className="font-bold text-base text-slate-900 hover:text-blue-600 cursor-pointer mt-1"
|
className="text-left font-bold text-base text-slate-900 hover:text-blue-600 cursor-pointer mt-1">
|
||||||
>
|
{t.baslik}
|
||||||
{t.baslik}
|
</button>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-bold text-slate-500 bg-slate-100 px-2.5 py-1 rounded-md">
|
<span className="text-xs font-bold text-slate-500 bg-slate-100 px-2.5 py-1 rounded-md">
|
||||||
@@ -72,6 +73,7 @@ export const DailyBulletin = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
type="button"
|
||||||
onClick={() => setActiveTenderDetail(t)}
|
onClick={() => setActiveTenderDetail(t)}
|
||||||
className="text-xs font-bold text-blue-600 hover:text-blue-800 flex items-center gap-1 hover:underline"
|
className="text-xs font-bold text-blue-600 hover:text-blue-800 flex items-center gap-1 hover:underline"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ try {
|
|||||||
await page.waitForLoadState('networkidle');
|
await page.waitForLoadState('networkidle');
|
||||||
evidence.checks.visibleCities = await Promise.all(['Giresun', 'Kayseri', 'Akdeniz', 'Aksaray', 'Tepecik'].map(async city => ({ city, count: await page.getByText(city, { exact: false }).count() })));
|
evidence.checks.visibleCities = await Promise.all(['Giresun', 'Kayseri', 'Akdeniz', 'Aksaray', 'Tepecik'].map(async city => ({ city, count: await page.getByText(city, { exact: false }).count() })));
|
||||||
if (evidence.checks.visibleCities.some(item => item.count < 1)) throw new Error('Beş sentetik şehirden biri görünmedi.');
|
if (evidence.checks.visibleCities.some(item => item.count < 1)) throw new Error('Beş sentetik şehirden biri görünmedi.');
|
||||||
|
await page.getByRole('button', { name: 'Günlük Bülten', exact: true }).click();
|
||||||
|
await page.getByRole('heading', { name: 'Günlük İhale Bülteni', exact: true }).waitFor({ state: 'attached', timeout: 10_000 });
|
||||||
|
evidence.checks.dailyBulletinHeading = await page.getByRole('heading', { name: 'Günlük İhale Bülteni', exact: true }).count() === 1;
|
||||||
|
if (!evidence.checks.dailyBulletinHeading) throw new Error('Günlük bülten başlığı açılmadı.');
|
||||||
|
await page.getByRole('button', { name: 'Ana İhale Listesi', exact: true }).click();
|
||||||
await page.getByRole('button', { name: 'Pazar', exact: true }).click();
|
await page.getByRole('button', { name: 'Pazar', exact: true }).click();
|
||||||
await page.getByRole('button', { name: 'Analitik Dashboard', exact: true }).click();
|
await page.getByRole('button', { name: 'Analitik Dashboard', exact: true }).click();
|
||||||
await page.getByLabel('Ciro hedefi (TL)', { exact: true }).waitFor({ state: 'attached', timeout: 10_000 });
|
await page.getByLabel('Ciro hedefi (TL)', { exact: true }).waitFor({ state: 'attached', timeout: 10_000 });
|
||||||
|
|||||||
Reference in New Issue
Block a user